package tt.dz.service.imp.middleware;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import redis.clients.jedis.Jedis;
import tt.dz.dao.ext.charger.OmsChargerBespeakBillRecordDao;
import tt.dz.dao.ext.charger.OmsChargerChargeBillRecordDao;
import tt.dz.dao.ext.charger.OmsChargerChargeDirectRecordDao;
import tt.dz.dao.ext.charger.OmsChargerDao;
import tt.dz.dao.ext.charger.OmsChargerSoftwareRefreshDao;
import tt.dz.dao.ext.charger.OmsChargerStateAlternateDao;
import tt.dz.dao.ext.charger.OmsChargerStateDirectDao;
import tt.dz.dao.ext.dic.OmsPubParamDao;
import tt.dz.entity.base.JsonCommon;
import tt.dz.entity.base.OmsPubParam;
import tt.dz.entity.charger.OmsCharger;
import tt.dz.entity.charger.OmsChargerBespeakBillRecord;
import tt.dz.entity.charger.OmsChargerChargeBillRecord;
import tt.dz.entity.charger.OmsChargerChargeDirectRecord;
import tt.dz.entity.charger.OmsChargerErrorRecord;
import tt.dz.entity.charger.OmsChargerSoftwareRefresh;
import tt.dz.entity.charger.OmsChargerStateAlternate;
import tt.dz.entity.charger.OmsChargerStateDirect;
import tt.dz.entity.exception.BizException;
import tt.dz.service.charger.OmsChargerErrorRecordService;
import tt.dz.service.middleware.MessageService;
import tt.dz.service.middleware.OmsBespeakService;
import tt.dz.service.middleware.OmsChargeService;
import tt.dz.tcp.rpc.as.SystemAppServerRpcClient;
import tt.dz.tcp.rpc.as.client.constant.AppServerConstant;
import tt.dz.tcp.rpc.as.client.entity.AppChargeNotifyParam;
import tt.dz.tcp.rpc.ms.SystemMasterServerRpcClient;
import tt.dz.tcp.rpc.ms.client.entity.MasterQueryOfflineCardVO;
import tt.dz.tcp.rpc.os.OrderRpcClient;
import tt.dz.tcp.socket.MessageFuture;
import tt.dz.tcp.socket.exception.CreateConnectionFailException;
import tt.dz.tcp.socket.exception.DuplicateInstructionException;
import tt.dz.tcp.socket.exception.RetryFailException;
import tt.dz.util.CardUtils;
import tt.dz.util.OmsConstant;
import tt.dz.util.RedisClient;
import tt.dz.util.StringUtil;
import tt.dz.util.serialGenerater;

@Service @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class OmsChargeServiceImpl implements OmsChargeService{
	private Log log = LogFactory.getLog(OmsChargeServiceImpl.class);

	@Resource
	OmsChargerDao omsChargerDao;
	@Resource
	OmsChargerStateDirectDao omsChargerStateDirectDao;
	@Resource
	OmsChargerStateAlternateDao omsChargerStateAlternateDao;
	@Resource
	OmsChargerBespeakBillRecordDao omsChargerBespeakBillRecordDao;
	@Resource
	OmsChargerChargeBillRecordDao omsChargerChargeBillRecordDao;
	@Resource
	OmsPubParamDao omsPubParamDao;
	@Resource
	OmsChargerChargeDirectRecordDao omsChargerChargeDirectRecordDao;
	@Resource
	OmsChargerSoftwareRefreshDao omsChargerSoftwareRefreshDao;
	@Resource(name = "ev3cMessageServiceImpl")
	MessageService ev3cMessageService;
	@Resource(name = "ev3c2MessageServiceImpl")
	MessageService ev3c2MessageService;
	@Resource
	MessageWrapper messageWrapper;
	@Resource
	PriceService priceService;
	@Resource
	OrderRpcClient orderRpcClient;
	@Resource
	SystemAppServerRpcClient systemAppServerRpcClient;
	@Resource
	OmsBespeakService omsBespeakService;
	@Resource
	OmsChargerErrorRecordService omsChargerErrorRecordService;
	@Resource
	SystemMasterServerRpcClient masterServerRpcClient;

	@Value(value="${charging.data.upload.interval}")
	private int charging_data_upload_interval;

	@Value(value="${charging.battery.upload.interval}")
	private int charging_battery_upload_interval;
	
	private static Lock lock = new ReentrantLock(); // 锁对象

	String ev3c_frameCode, ev3c_msgHeader, ev3c_msgBody, protocol_type = "", protocol_version = "";
	JsonCommon<String> json = new JsonCommon<String>();

	@Override
	public MessageFuture startCharge(Map<String, String> map) throws Exception
	{
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		if (protocol_type == null)
		{
			protocol_type = "1";
		}
		if (protocol_version == null)
		{
			protocol_version = "0201";
		}
		String data = map.get("data");

		MessageFuture future = null;
		switch (protocol_type)
		{
			case "1":
				ev3c_frameCode = "10";
				switch (protocol_version)
				{
					case "0101":
					case "0102":
					case "0103":
						future = ev3c0101StartCharge(map, data);
						break;
					case "0201":
						log.info("protocol_version 0201");
						future = ev3c0201StartCharge(map, data);
						break;
					default:
						break;
				}
				break;
			default:
				break;
		}
//		log.debug(json.getCode() + " " + json.getMsg() + " " + json.getPojo());
		return future;

	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private MessageFuture ev3c0201StartCharge(Map<String, String> map, String data) throws BizException, RetryFailException, CreateConnectionFailException
	{
		//信息体
		log.info("Start");
		log.info(map);
		String portNo = map.get("portNo"); //00表示A口，01表示B口……
		log.info(portNo);
		String controlType = map.get("controlType");  //控制类型见下表对应数据，如0x04为即时开启/BMS充电/自动充满方式
		if(StringUtils.isEmpty(controlType)){
			controlType ="04";
		}
		String openRestrictedData = map.get("openRestrictedData");
		if(StringUtils.isEmpty(openRestrictedData))
			openRestrictedData = "00000000";

		String userCard = map.get("userCard");
		log.info(userCard);

		String data_interval = Integer.toHexString(charging_data_upload_interval);
		String battery_interval = Integer.toHexString(charging_battery_upload_interval);

		if(controlType.length() == 1)
			controlType = "0" + controlType;
		if(data_interval.length() == 1)
			data_interval = "0" + data_interval;
		if(battery_interval.length() == 1)
			battery_interval = "0" + battery_interval;

		//信息头
		String chargerId = map.get("chargerId");
		log.info(chargerId);
		OmsCharger chargerquery = new OmsCharger()				;
		chargerquery.setCharger_id(chargerId);
		chargerquery.setValid_flag(1);
		OmsCharger charger = omsChargerDao.findOneExample(chargerquery, null, null);
		if(charger == null)
			throw new BizException("Charger not found");
		//pengyu modify 20180427  注释了这部分后，如果从其他地方调用这个接口，可能出现存在未支付的订单，但是却支付了的情况。其他调用的地方需要先判断是否有未支付的订单，也就是把这段代码放到另外调用这个方法之前。
//		if (!omsBespeakService.checkBespeakOrderNoPayInfo(userCard) || !omsBespeakService.checkChargerOrderNoPayInfo(userCard))
//			throw new BizException(OmsConstant.ErrorCodeEnum.BespeakResultExistNotPayOrder.value(), "存在未支付的订单");

		Date now = new Date();

		String frameCode="13";
		int chargerType = charger.getCharger_type();
		String encryption = "00";

		String random_code = Ev3c2EncapsulationServiceImpl.getRandom4int();

		String body = controlType + openRestrictedData + userCard + data_interval + battery_interval + random_code;
		log.info(body);
		String msg = messageWrapper.wrapSendingMsg(body, frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);
		log.info(msg);
		//写入数据库
		OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord();

		String serialNo = msg.substring(32, 50);
		String charge_jrnl = chargerId + String.format("%02d", Integer.valueOf(portNo)) + serialNo;

		billRecord.setCharge_jrnl(charge_jrnl);
		billRecord.setMsg_charge_jrnl(serialNo);
		billRecord.setCharger_id(chargerId);
		billRecord.setStation_id(charger.getStation_id());
		billRecord.setPort_no(Integer.valueOf(portNo));
		billRecord.setUser_pay_card(userCard);
		billRecord.setStart_time(now);
		billRecord.setStatus(OmsConstant.ChargingBillStatus.NotifyCharging);
		billRecord.setCreate_time(now);
		billRecord.setValid_flag(1);
		//查询桩是否被预约，如果没有预约，就不需要做关联。
//		int chargerType = charger.getCharger_type();

		//		{//通过用户卡号、电桩地址、当前系统时间在预约开始时间和预约理论结束时间之间 来查询预约费用记录表
		String whereClause = String.format("WHERE user_pay_card ='%1$s' AND charger_id ='%2$s' AND port_no = %3$s AND STATUS = %4$d AND valid_flag =1 AND oms_msg_bespeak_end_jrnl is null", userCard, chargerId, portNo, OmsConstant.BespeakStatus.Reserved);
		OmsChargerBespeakBillRecord bespeakBillRecord = omsChargerBespeakBillRecordDao.findOneExampleByCondition(new OmsChargerBespeakBillRecord(), whereClause);

		if (bespeakBillRecord != null && (now.after(bespeakBillRecord.getStart_time())))
		{
			log.info(bespeakBillRecord.getOms_msg_bespeak_jrnl());
			//证明了之前的预约记录是这个人的而且在预约时间范围内
			String bespeakJrnl = bespeakBillRecord.getBespeak_jrnl();
			billRecord.setBespeak_jrnl(bespeakJrnl);

			bespeakBillRecord.setOms_msg_bespeak_end_jrnl(msg.substring(32, 50));
			omsChargerBespeakBillRecordDao.updateObject(bespeakBillRecord);
		}
		omsChargerChargeBillRecordDao.save(billRecord);

		Jedis jedis = null;
		try
		{
			jedis = RedisClient.getConnect();
			String key = chargerId + String.format("%02d", Integer.valueOf(portNo)) + "_status";
			if (jedis.get(key) != null)
				jedis.del(key);
		}
		catch (Exception e)
		{
			log.error(e.getMessage(), e);
		}
		finally
		{
			if (jedis != null)
				jedis.close();
		}

		MessageFuture future = null;
		try
		{
		 	future = ev3c2MessageService.sendNoWait(msg, chargerId);
		}
		catch (RetryFailException | CreateConnectionFailException | DuplicateInstructionException e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}


		return future;
	}

	/**
	 * 针对0101或0102 版本协议
	 * 开启充电执行流程如下:
	 * 0:查询相关预约信息，如果之前有预约，则update预约记录表，状态置为已结束预约，不生成订单。
	 * 1.更新直流或交流表信息;生成流水号,并插入充电费用记录表(状态修改为已下发开启中)
     * 2.下发报文
     * 
     * 特别地:充电开始时,查询预约费用表和充电费用表:如果有未支付订单(存在订单号而且未支付),则不允许充电;
     * 如果有;则调用订单服务器接口把未支付订单号列表提供给OS,查询后确认这些是否已支付:如果已支付,就回写数据库相关记录,并允许充电
     * 
	 * @param map
	 * @param data
	 * @return JsonCommon<String>
	 */
	private MessageFuture ev3c0101StartCharge(Map<String, String> map, String data) throws BizException, RetryFailException, CreateConnectionFailException
	{
		log.info("Receive response message from startCharge! curTime = " + new Date().getTime());
		ev3c_frameCode = "10";
		String chargerId, bespeakJrnl;
		chargerId = map.get("chargerId");
		String userCard = map.get("userCard");
		map.put("portNo", Ev3cEncapsulationServiceImpl.portNoWithMsg(map.get("portNo")));
		OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord();
		Date now = new Date();
		String serialNo = serialGenerater.generateSerialNo14(); // 序列号
		if (StringUtil.isBlank(map.get("chargerId")) || !StringUtil.isNumeric(map.get("portNo")) || StringUtil.isBlank(map.get("userCard")))
		{
			log.error("Charger id or portNo or userCard do not exist");
			throw new BizException(OmsConstant.ErrorCodeEnum.MessageMissParam.value(), OmsConstant.ErrorCodeEnum.MessageMissParam.desc());
		}

		if (map.get("protocol_version").equals("0102"))
		{
			ev3c_msgBody = map.get("portNo") + map.get("controlType") + map.get("openRestrictedData") + map.get("timeStart") + userCard;
		}
		else
		{
			ev3c_msgBody = "00040000000000000000" + userCard;
		}

		map.put("portNo", Ev3cEncapsulationServiceImpl.portNoWithDb(map.get("portNo")));

		OmsChargerStateDirect directState = null;
		OmsChargerStateAlternate alternateState = null;
		String charge_port = map.get("portNo");  // 充电口号
		int port_no = Integer.parseInt(charge_port, 2);
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		charger_query.setValid_flag(1);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger == null || charger.getCharger_type() == null)
			throw new BizException("400", "charger not found");

		// 特别地:充电开始时,查询预约费用表和充电费用表:如果有未支付订单(存在订单号而且未支付),则不允许充电;
		// 如果有;则调用订单服务器接口把未支付订单号列表提供给OS,查询后确认这些是否已支付:如果已支付,就回写数据库相关记录,并允许充电
		if (!omsBespeakService.checkBespeakOrderNoPayInfo(userCard))
		{
			log.error("chargerId " + chargerId + " userCard " + userCard + " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:Exist not pay order!");
			throw new BizException(OmsConstant.ErrorCodeEnum.BespeakResultExistNotPayOrder.value(), "chargerId " + chargerId + " userCard " + userCard + " Exist not pay order!");
		}

		if (!omsBespeakService.checkChargerOrderNoPayInfo(userCard))
		{
			log.error("chargerId " + chargerId + " userCard " + userCard + " Class:OmsBespeakServiceImpl -> method:ev3c0101Bespeak -> result:Exist not pay order!");
			throw new BizException(OmsConstant.ErrorCodeEnum.BespeakResultExistNotPayOrder.value(), "chargerId " + chargerId + " userCard " + userCard + " Exist not pay order!");
		}

		//通过当前时间  + 桩地址  ,生成流充电水号
		String chargeJrnl = "";
		chargeJrnl = chargerId + String.format("%02d", port_no) + serialGenerater.generateSerialNo();
		billRecord.setCharge_jrnl(chargeJrnl); //  设置充电流水号

		int chargerType = charger.getCharger_type();
		int isBespeak = 0; // 1:预约充电,2:直接充电
		String curBespeakUserCard = ""; // 当前预约卡号
		try
		{
			lock.lock(); // 得到锁
			switch (chargerType)
			{ // 1:直流  2:交流  3:混合
				case 1:
					OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
					directState_query.setPort_no(port_no);
					directState_query.setCharger_id(chargerId);
					directState = omsChargerStateDirectDao.findOneExample(directState_query, null, null);
					if ((directState.getOnline_status() == 1) && (directState.getCharge_status() == 1) && (directState.getCable_status() == 1))
					{
						isBespeak = 1;
						curBespeakUserCard = directState.getUser_pay_card();
					}
					break;
				case 2:
					OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
					alternateState_query.setPort_no(port_no);
					alternateState_query.setCharger_id(chargerId);
					alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
					if ((alternateState.getOnline_status() == 1) && (alternateState.getCharge_status() == 1) && (alternateState.getCable_status() == 1))
					{
						isBespeak = 1;
						curBespeakUserCard = alternateState.getUser_pay_card();
					}
					break;
				default:
					break;
			}

			if (isBespeak == 1)
			{ // 通过用户卡号、电桩地址、当前系统时间在预约开始时间和预约理论结束时间之间 来查询预约费用记录表
				log.info("Receive response message from startCharge(isBespeak status is Bespeaked) = " + curBespeakUserCard);
				if (!userCard.equals(curBespeakUserCard))
				{ // 当前充电卡号不是预约卡号,不允许充电
					json.setCode(OmsConstant.ErrorCodeEnum.BespeakResultChargerBespeaked.value()); // 失败错误码
					json.setMsg("chargerId " + chargerId + " userCard " + curBespeakUserCard + " The charger has been booking!");
					log.error("chargerId " + chargerId + " userCard " + curBespeakUserCard + " Class:OmsChargeServiceImpl -> method:ev3c0101StartCharge -> result:The charger has been booking!");
					//					return json;
				}
//				OmsChargerBespeakBillRecord bespeakBillRecord_query = new OmsChargerBespeakBillRecord();
//				bespeakBillRecord_query.setCharger_id(chargerId);
//				bespeakBillRecord_query.setUser_pay_card(userCard);
//				bespeakBillRecord_query.setPort_no(port_no);

				String whereClause = String.format("WHERE user_pay_card ='%1$s' AND charger_id ='%2$s' AND port_no = %3$s AND STATUS = %4$d AND valid_flag =1 AND oms_msg_bespeak_end_jrnl is null", userCard, chargerId,
						port_no, OmsConstant.BespeakStatus.Reserved);
				OmsChargerBespeakBillRecord bespeakBillRecord = omsChargerBespeakBillRecordDao.findOneExampleByCondition(new OmsChargerBespeakBillRecord(), whereClause);

//				OmsChargerBespeakBillRecord bespeakBillRecord = omsChargerBespeakBillRecordDao.findOneExample(bespeakBillRecord_query, "start_time", "desc");
				if (bespeakBillRecord == null)
				{ // 如果查询不到结果,就说明被另外的人预约了然后这个用户去充电
					log.error("no record found");
					//throw new BizException("400", "charger has been reserved by other user");
					throw new BizException(OmsConstant.ErrorCodeEnum.ChargeResultChargerBespeaked.value(), OmsConstant.ErrorCodeEnum.ChargeResultChargerBespeaked.desc());
				}
				else
				{
					log.debug(bespeakBillRecord.getStart_time());
					//					if ((bespeakBillRecord.getValid_flag() == 1) && (now.compareTo(bespeakBillRecord.getStart_time()) >= 0)
					//							&& (now.compareTo(bespeakBillRecord.getEstimate_end_time()) <= 0)){
					if ((bespeakBillRecord.getValid_flag() == 1) && (now.compareTo(bespeakBillRecord.getStart_time()) >= 0))
					{ // 证明了之前的预约记录是这个人的而且在预约时间范围内
						bespeakJrnl = bespeakBillRecord.getBespeak_jrnl();
						billRecord.setBespeak_jrnl(bespeakJrnl); // 预约流水号
						bespeakBillRecord.setActual_end_time(now); // 预约实际结束时间
						// TODO peizhide 时长
						bespeakBillRecord.setIs_done(0);// 未完成订单
//						bespeakBillRecord.setStatus(5); // 预约状态:1:预约中  2:已预约  3:取消预约中  4:已取消预约  5:充电(流程1:1-2-3-4, 流程2:1-2-5)
						billRecord.setBespeak_jrnl(bespeakJrnl);
						omsChargerBespeakBillRecordDao.updateObject(bespeakBillRecord); // 更新预约记录表
						log.debug(bespeakBillRecord.getStart_time());
						log.debug(bespeakBillRecord.getActual_end_time());
					}
				}
			}

			log.info("Receive response message from startCharge(chargeJrnl) = " + chargeJrnl);
			String oms_msg_charge_jrnl = serialNo;
			billRecord.setMsg_charge_jrnl(oms_msg_charge_jrnl);
			billRecord.setCharger_id(chargerId);
			billRecord.setUser_pay_card(userCard);
			billRecord.setStation_id(charger.getStation_id());
			billRecord.setStart_time(now);
			billRecord.setStatus(0); // 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)  2:电充满未结束(如未拔枪则是此状态)  3:关闭充电(已下发指令)  4:充电结束(桩回复充电结束)  5:已生成账单  6:已结算  7:已退款  8:充电失败
			billRecord.setPort(port_no);
			billRecord.setValid_flag(1);
			billRecord.setPort_no(port_no);
			// 线上卡是18808开头,线下卡是18806开头
			if (userCard.startsWith("18808"))
			{
				billRecord.setOffline_is_pay(2);
			}
			else
			{
				billRecord.setOffline_is_pay(0);
			}
			omsChargerChargeBillRecordDao.save(billRecord);

			// 更新充电状态
			switch (chargerType)
			{ // 1:直流  2:交流  3:混合
				case 1:
					directState.setCharge_jrnl(chargeJrnl); // 下发报文充电开始流水号(报文开始充电流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20 0x15 0x05 0x10 0x21 0x45 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
					omsChargerStateDirectDao.updateObject(directState);
					break;
				case 2:
					alternateState.setCharge_jrnl(chargeJrnl); // 下发报文充电开始流水号(报文开始充电流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20 0x15 0x05 0x10 0x21 0x45 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
					omsChargerStateAlternateDao.updateObject(alternateState);
					break;
				default:
					break;
			}

		}
		catch (Exception e)
		{
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " startCharge fail! " + e.getMessage());
			log.error("chargerId " + chargerId + " startCharge fail! " + e.getMessage());
		}
		finally
		{
			lock.unlock(); // 释放锁
		}


		Jedis jedis = null;
		try
		{
			jedis = RedisClient.getConnect();
			String key = chargerId + String.format("%02d", port_no) + "_status";
			if (jedis.get(key) != null)
				jedis.del(key);
		}
		catch (Exception e)
		{
			log.error(e.getMessage(), e);
		}
		finally
		{
			if(jedis != null)
				jedis.close();
		}

		// 下发报文
		ev3c_msgBody = "00040000000000000000" + userCard;
		ev3c_msgHeader = "68" + StringUtil.ev3cMsgBodyBin(ev3c_msgBody) + "01" + "000000" + "0001" + chargerId + ev3c_frameCode + serialNo;

		MessageFuture future = null;
		try
		{
			log.info("Send message to startCharge sendNoWait! curTime = " + new Date().getTime());
			future = ev3cMessageService.sendNoWait(ev3c_msgHeader + ev3c_msgBody, chargerId);
			log.debug("chargerId " + chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StartCharge -> result:startCharge success!");
		}
		catch (RetryFailException | CreateConnectionFailException | DuplicateInstructionException e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}

		return future;
	}

/*	private MessageFuture ev3c0102StartCharge(Map<String, String> map, String data) throws CreateConnectionFailException, BizException, RetryFailException
	{
		return ev3c0101StartCharge(map, data);
	}*/
/*

	private JsonCommon<String> ev3c0103StartCharge(Map<String, String> map, String data) {
		//信息体
		String portNo = map.get("portNo"); //00表示A口，01表示B口……
		if(StringUtil.isBlank(portNo)){
			portNo ="00";
		}
		String controlType = map.get("controlType");  //控制类型见下表对应数据，如0x04为即时开启/BMS充电/自动充满方式
		if(StringUtil.isBlank(controlType)){
			controlType ="04";
		}
		String openRestrictedData = map.get("openRestrictedData");
		if(StringUtil.isBlank(openRestrictedData)){
			openRestrictedData ="00000000";
		}else{
			int param = 1;
			if(controlType.endsWith("1")){
				param = 100;
				openRestrictedData = StringUtil.float10to16ByParamDesc(openRestrictedData, param, 8);
			}else if(controlType.endsWith("2")){
				param = 1;
				openRestrictedData = StringUtil.float10to16ByParamDesc(openRestrictedData, param, 8);
			}else if(controlType.endsWith("3")){
				param = 100;
				openRestrictedData = StringUtil.float10to16ByParamDesc(openRestrictedData, param, 8);
			}
		}
		String startTime = map.get("startTime");
		if(StringUtil.isBlank(startTime)){
			startTime ="00000000";
		}
		String userCard = map.get("userCard");
		String charging_data_upload_interval = map.get("charging_data_upload_interval");
		if(charging_data_upload_interval == null){
			charging_data_upload_interval = Integer.toHexString(60);//60秒一次
		}
		String battery_details_upload_interval = map.get("battery_details_upload_interval");
		if(battery_details_upload_interval == null){
			battery_details_upload_interval = Integer.toHexString(60);//60秒一次
		}
		//信息头
		String chargerId = map.get("chargerId");
		String communicationNo = map.get("communicationNo");
		if(StringUtil.isBlank(communicationNo)){
			communicationNo ="0001";
		}
		if((!StringUtil.isNumeric(charging_data_upload_interval))||(!StringUtil.isNumeric(battery_details_upload_interval))){//如果充电数据上传间隔或电池详情上传间隔没有赋值，就从数据库中取出默认值
			List<OmsPubParam> list_pubParam  = omsPubParamDao.findListByCondition(new OmsPubParam(), " where param_name in ('charging_data_upload_interval','battery_details_upload_interval')");
			for(OmsPubParam omsPubParam : list_pubParam){
				if(omsPubParam.getParam_name().equals("charging_data_upload_interval")){
					charging_data_upload_interval = omsPubParam.getParam_value();
				}
				if(omsPubParam.getParam_name().equals("battery_details_upload_interval")){
					battery_details_upload_interval = omsPubParam.getParam_value();
				}
			}
		}
		//充电数据上传间隔和电池详情上传间隔放入redis中，生命时长为XXX秒
		Map<String, String> hashMap = new HashMap<String, String>();
		hashMap.put("charging_data_upload_interval", charging_data_upload_interval);
		hashMap.put("battery_details_upload_interval", battery_details_upload_interval);
		String key = chargerId+"_upload_interval";
		RedisClient.putMap(key, hashMap);
		RedisClient.expire(key, 60*60*24);//24小时
		ev3c_msgBody = portNo+controlType+openRestrictedData+startTime+userCard+charging_data_upload_interval+battery_details_upload_interval;
//		ev3c_msgBody = "00040000000000000000"+userCard;
		ev3c_msgHeader ="68"+StringUtil.ev3cMsgBodyBin(ev3c_msgBody)+"01"+"000000"+communicationNo+chargerId+ev3c_frameCode+StringUtil.now14time();
//		StringUtil.sendSocket(ev3c_msgHeader+ev3c_msgBody);//
		try {
			ev3cMessageService.sendNoWait(ev3c_msgHeader+ev3c_msgBody, chargerId);
		} catch (RetryFailException e) {
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId "+ chargerId +" startCharge sendSocket fail "+e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId "+ chargerId +" startCharge sendSocket fail "+e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId "+ chargerId +" startCharge sendSocket fail "+e.getMessage());
			return json;
		}
		JsonCommon<String> json = new JsonCommon<String>();
		json.setCode("200");
		json.setMsg("chargerId "+ chargerId +" startCharge sendSocket success");
		return json;
	}
*/

	@Override
	public JsonCommon<String> startChargeReturn(Map<String,String> map) {
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		switch (protocol_type) {
		case "1":
			ev3c_frameCode = "56";
			switch (protocol_version) {
			case "0101":
//				json = ev3c0101StartChargeReturn(map);
//				break;
			case "0102":
				json = ev3c0102StartChargeReturn(map);
				break;
			case "0103":
				json = ev3c0103StartChargeReturn(map);
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		return json;




	}

	/**
	 * 针对0101或0102 版本协议
	 * 开启充电执行流程如下:
	 * 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表，再回调)
	 * 2.如果响应码不为000000,根据实际情况判断是否需要更新直流或交流表信息;更新充电费用记录表(状态为回复)
	 * 3.AS或第三方回调,推送说明已经开启
   	 * 
   	 * 预约费用表状态:
   	 * 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)  2:电充满未结束(如未拔枪则是此状态)  3:关闭充电(已下发指令)  4充电结束:桩回复充电结束)  5:已生成账单  6:已结算  7:已退款  8:充电失败
	 * @param map
	 * @return JsonCommon<String>
	 */
	private JsonCommon<String> ev3c0101StartChargeReturn(Map<String, String> map)
	{
		String data = map.get("data");
		String responseCode = data.substring(8, 14); // 获取响应码
		String userCard = map.get("userCard");  //用户卡号
		String chargerId, bespeakJrnl, responseMsgHeader = null, responseMsgBody = null;
		chargerId = map.get("chargerId");
		JsonCommon<String> json = new JsonCommon<String>();
		// 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调);否则进入第二步。
		if (OmsBespeakServiceImpl.checkChargerReplyMessageStatus(responseCode))
		{ // 正常
			OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord(); // 充电费用记录表
			Date now = new Date();
			OmsChargerStateDirect directState;
			OmsChargerStateAlternate alternateState;
			String charge_port = map.get("charge_port");  //充电口号
			int port_no = Integer.parseInt(charge_port, 2);

			OmsCharger charger_query = new OmsCharger();
			charger_query.setCharger_id(chargerId);
			OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
			if (charger == null || charger.getCharger_type() == null)
			{
				json.setCode("400");
				json.setMsg("charger not found");
				responseMsgHeader = data.substring(0, 8) + OmsConstant.MsgResponseCodeEnum.SysError.value() + data.substring(14, 34) + ev3c_frameCode + data.substring(36, 50);
				json.setPojo(responseMsgHeader);
				return json;
			}
			//查询桩是否被预约,如果没有预约,就不需要做关联。
			int chargerType = charger.getCharger_type();
			int isBespeak = 0;
			switch (chargerType)
			{ // 1:直流  2:交流  3:混合
				case 1:
					OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
					directState_query.setPort_no(port_no);
					directState_query.setCharger_id(chargerId);
					directState = omsChargerStateDirectDao.findOneExample(directState_query, null, null);
					if ((directState.getOnline_status() == 1) && (directState.getCharge_status() == 1) && (directState.getCable_status() == 1))
					{
						isBespeak = 1;
					}
					directState.setCharge_status(2);
					omsChargerStateDirectDao.updateObject(directState);
					break;
				case 2:
					OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
					alternateState_query.setPort_no(port_no);
					alternateState_query.setCharger_id(chargerId);
					alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
					if ((alternateState.getOnline_status() == 1) && (alternateState.getCharge_status() == 2) && (alternateState.getCable_status() == 1))
					{
						isBespeak = 1;
					}
					alternateState.setCharge_status(2);
					omsChargerStateAlternateDao.updateObject(alternateState);
					break;
				default:
					break;
			}
			if (isBespeak == 1)
			{ // 通过用户卡号、电桩地址、当前系统时间在预约开始时间和预约理论结束时间之间 来查询预约费用记录表
				OmsChargerBespeakBillRecord bespeakBillRecord_query = new OmsChargerBespeakBillRecord();
				bespeakBillRecord_query.setCharger_id(chargerId);
				bespeakBillRecord_query.setUser_pay_card(userCard);
				bespeakBillRecord_query.setPort_no(port_no);
				OmsChargerBespeakBillRecord bespeakBillRecord = omsChargerBespeakBillRecordDao.findOneExample(bespeakBillRecord_query, null, null);
				if (bespeakBillRecord == null)
				{ // 如果查询不到结果,就说明被另外的人预约了然后这个用户去充电
				}
				else
				{
					if ((bespeakBillRecord.getValid_flag() == 1) && (now.compareTo(bespeakBillRecord.getStart_time()) >= 0))
					{
						//							&& (now.compareTo(bespeakBillRecord.getEstimate_end_time()) <= 0)){
						// 证明了之前的预约记录是这个人的而且在预约时间范围内
						bespeakJrnl = bespeakBillRecord.getBespeak_jrnl();
						billRecord.setBespeak_jrnl(bespeakJrnl);
						billRecord.setStatus(1); // 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)  2:电充满未结束(如未拔枪则是此状态)  3:关闭充电(已下发指令)  4充电结束:桩回复充电结束)  5:已生成账单  6:已结算  7:已退款  8:充电失败
					}
				}
			}
			omsChargerChargeBillRecordDao.updateObject(billRecord);

			responseMsgHeader = "680000" + data.substring(6, 34) + "56" + data.substring(36);
			responseMsgBody = "";

			// 通知appServer start
			AppChargeNotifyParam obj = new AppChargeNotifyParam();
			obj.setAction(AppServerConstant.CHARGE_NOTIFY_ACTION_CHARGE); // 开始充电
			if (billRecord.getBespeak_jrnl() == null || "".equals(billRecord.getBespeak_jrnl()))
			{
				obj.setChargeType("0"); // 非预约充电
			}
			else
			{
				obj.setChargeType("1"); // 预约充电
			}
			obj.setStationName(charger.getStation_name());
			obj.setSerialNo(charger.getSerial_no());
			obj.setPlugNo(String.valueOf(billRecord.getPort_no()));
			obj.setChargerId(chargerId);
			obj.setUserCard(userCard);
			obj.setChargeSn(billRecord.getCharge_jrnl());
			obj.setStartTime(billRecord.getStart_time().toString());
			json.setPojo(billRecord.toString());
			json = systemAppServerRpcClient.chargeNotify(obj);
			// 通知appServer end
		}
		else
		{ // 入库oms_charger_error_record[故障记录表]
			OmsChargerErrorRecord record = new OmsChargerErrorRecord();
			record.setCharger_id(chargerId);
			record.setError_code(responseCode);
			record.setError_msg("charger fault");
			record.setStatus(0); // 0:未处理,1:已处理
			record.setValid_flag(1);
			record.setCreate_oper_id("000");
			record.setCreate_time(new Date());
			omsChargerErrorRecordService.add(record);

			json.setCode(OmsConstant.ErrorCodeEnum.ConnectionResultChargerException.value());
			json.setMsg("chargerId " + chargerId + "userCard " + userCard + " ev3c0101BespeakReturn: bespeakReturn connection status fail!"); // 带卡号
			log.error("chargerId " + chargerId + " Class:OmsBespeakServiceImpl -> method:ev3c0101BespeakReturn -> result:bespeakReturn connection status fail!");
		}

		return StringUtil.getjsonCReturn(responseMsgHeader, responseMsgBody, "200", "ok");
	}

	/**
	 * 针对0102版本协议
	 * 开启充电执行流程如下:
	 * 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表，再回调)
	 * 2.如果响应码不为000000,根据实际情况判断是否需要更新直流或交流表信息;更新充电费用记录表(状态为回复)
	 * 3.AS或第三方回调,推送说明已经开启
   	 * 
   	 * 预约费用表状态:
   	 * 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)  2:电充满未结束(如未拔枪则是此状态)  3:关闭充电(已下发指令)  4充电结束:桩回复充电结束)  5:已生成账单  6:已结算  7:已退款  8:充电失败
	 * @param map
	 * @return JsonCommon<String>
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
	private JsonCommon<String> ev3c0102StartChargeReturn(Map<String, String> map)
	{
		try
		{
			log.info("Receive response message from startChargeReturn! curTime = " + new Date().getTime());
			String data = map.get("data");
			String responseCode = data.substring(8, 14); // 获取响应码
			String userCard = map.get("userCard");  //用户卡号
			String chargerId, responseMsgHeader = null, responseMsgBody = null;
			JsonCommon<String> json = new JsonCommon<String>();
			chargerId = map.get("chargerId");
			String chargeJrnl = null;

			Date now = new Date();
			OmsChargerStateDirect directState = null;
			OmsChargerStateAlternate alternateState = null;
			String charge_port = map.get("charge_port");  //充电口号
			int port_no = Integer.parseInt(charge_port, 2);
			OmsCharger charger_query = new OmsCharger();
			charger_query.setCharger_id(chargerId);
			OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
			if (charger == null || charger.getCharger_type() == null)
			{
				json.setCode("400");
				json.setMsg("charger not found!");
				responseMsgHeader = data.substring(0, 8) + OmsConstant.MsgResponseCodeEnum.SysError.value() + data.substring(14, 34) + ev3c_frameCode + data.substring(36, 50);
				json.setPojo(responseMsgHeader);
				return json;
			}
			log.debug("charger found");

			// 查询桩是否被预约,如果没有预约,就不需要做关联。
			int chargerType = charger.getCharger_type();
			// 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调);否则进入第二步。
			if (OmsBespeakServiceImpl.checkChargerReplyMessageStatus(responseCode))
			{ // 正常

				log.info("Receive response message from startCharge(responseCode is normal)");
				OmsChargerChargeBillRecord billRecord_query = new OmsChargerChargeBillRecord();
				billRecord_query.setCharger_id(chargerId);
				billRecord_query.setUser_pay_card(userCard);
				billRecord_query.setStatus(0);
				OmsChargerChargeBillRecord chargebillRecord = omsChargerChargeBillRecordDao.findOneExample(billRecord_query, "start_time", "desc");
				log.info(chargebillRecord);
				if(chargebillRecord != null)
					log.info(chargebillRecord.getCharge_jrnl());
				int notifyFlag = 1; // 1:预约充电, 2:刷卡充电
				if (chargebillRecord == null)
				{ // 没有查询到充电费用信息,表示是刷卡充电情况
					log.info("offline");
					log.info(userCard);
					MasterQueryOfflineCardVO.MasterQueryOfflineCardParamVO vo = new MasterQueryOfflineCardVO.MasterQueryOfflineCardParamVO();
					vo.setCardNo(userCard);
					MasterQueryOfflineCardVO.MasterQueryOfflineCardRetVO retVO = masterServerRpcClient.queryOfflineCard(vo);
					if(retVO == null || retVO.getIsSuccess() != 1 || retVO.getCardState() != 1)
					{
						json.setCode("400");
						json.setMsg("chargerId " + chargerId + " startCharge fail! card No. is invalid");
						log.error("chargerId " + chargerId + " startCharge fail! card No. is invalid");
						log.error(retVO);
					}
					else
					{

						notifyFlag = 2;
						//通过当前时间  + 桩地址  ,生成流充电水号
						OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord();
						chargeJrnl = chargerId + String.format("%02d", port_no) + serialGenerater.generateSerialNo();
						billRecord.setCharge_jrnl(chargeJrnl); //  设置充电流水号
						/** 0:空闲  1:预约  2:充电  3:故障  4:占用中(针对双枪单充等情况) 5:刷卡中  8:离线*/
						int chargeStatus = 0; // 当前桩,对应枪口状态
						try
						{
							lock.lock(); // 得到锁
							switch (chargerType)
							{ // 1:直流  2:交流  3:混合
								case 1:
									OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
									directState_query.setPort_no(port_no);
									directState_query.setCharger_id(chargerId);
									directState = omsChargerStateDirectDao.findOneExample(directState_query, null, null);
									chargeStatus = directState.getCharge_status();

									directState.setCharge_status(2);
									directState.setBespeak_jrnl(null);
									directState.setCharge_jrnl(chargeJrnl); // 下发报文充电开始流水号(报文开始充电流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20 0x15 0x05 0x10 0x21 0x45 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
									omsChargerStateDirectDao.updateObject(directState);
									break;
								case 2:
									OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
									alternateState_query.setPort_no(port_no);
									alternateState_query.setCharger_id(chargerId);
									alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
									chargeStatus = alternateState.getCharge_status();

									alternateState.setCharge_status(2);
									alternateState.setBespeak_jrnl(null);
									alternateState.setCharge_jrnl(chargeJrnl); // 下发报文充电开始流水号(报文开始充电流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20 0x15 0x05 0x10 0x21 0x45 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
									omsChargerStateAlternateDao.updateObject(alternateState);
									break;
								default:
									break;
							}

							log.info(chargeStatus);
							if (chargeStatus == 0)
							{ // 当前桩,对应枪口状态为空闲
								log.info("Receive response message from startCharge(chargeJrnl)" + chargeJrnl);
								String oms_msg_charge_jrnl = serialGenerater.generateSerialNo();
								billRecord.setBespeak_jrnl(null);
								billRecord.setMsg_charge_jrnl(oms_msg_charge_jrnl);
								billRecord.setCharger_id(chargerId);
								billRecord.setUser_pay_card(userCard);
								billRecord.setStation_id(charger.getStation_id());
								billRecord.setStart_time(now);
								billRecord.setStatus(1); // 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)  2:电充满未结束(如未拔枪则是此状态)  3:关闭充电(已下发指令)  4:充电结束(桩回复充电结束)  5:已生成账单  6:已结算  7:已退款  8:充电失败
								billRecord.setPort(port_no);
								billRecord.setValid_flag(1);
								billRecord.setPort_no(port_no);
								// 线上卡是18808开头,线下卡是18806开头
								if (userCard.startsWith("18808"))
								{
									billRecord.setOffline_is_pay(2);
								}
								else
								{
									billRecord.setOffline_is_pay(0);
								}
								omsChargerChargeBillRecordDao.save(billRecord);
								log.debug("chargerId " + chargerId + " ev3c0102StartChargeReturn save = " + billRecord.toString());
							}

						}
						catch (Exception e)
						{
							json.setCode("400");
							json.setMsg("chargerId " + chargerId + " startCharge fail! " + e.getMessage());
							log.error("chargerId " + chargerId + " startCharge fail! " + e.getMessage());
						}
						finally
						{
							lock.unlock(); // 释放锁
						}
					}
				}
				else
				{ // 预约充电,第三方充电情况处理
					log.info("start charge");
					notifyFlag = 1;

					if (StringUtil.isNotBlank(chargebillRecord.getBespeak_jrnl()))
					{ // 预约转充电
						String bespeak_jrnl = chargebillRecord.getBespeak_jrnl();
						OmsChargerBespeakBillRecord bespeakBillRecord = omsChargerBespeakBillRecordDao.findOneExample(new OmsChargerBespeakBillRecord(bespeak_jrnl), "start_time", "desc");
						if (bespeakBillRecord != null)
						{
							bespeakBillRecord.setStatus(5); // 预约状态:1:预约中  2:已预约  3:取消预约中  4:已取消预约  5:充电(流程1:1-2-3-4, 流程2:1-2-5)
							omsChargerBespeakBillRecordDao.updateObject(bespeakBillRecord);
						}
						else
						{
							log.info("bespeak_jrnl in chargebillRecord not in bespeakBillRecord ");
						}
					}

					chargebillRecord.setStatus(1); // 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)  2:电充满未结束(如未拔枪则是此状态)  3:关闭充电(已下发指令)  4:充电结束(桩回复充电结束)  5:已生成账单  6:已结算  7:已退款  8:充电失败
					chargebillRecord.setVIN("test");
					omsChargerChargeBillRecordDao.updateObject(chargebillRecord);
					log.debug(chargebillRecord);
				}

				int isBespeak = 0;
				switch (chargerType)
				{ // 1:直流  2:交流  3:混合
					case 1:
						OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
						directState_query.setPort_no(port_no);
						directState_query.setCharger_id(chargerId);
						directState = omsChargerStateDirectDao.findOneExample(directState_query, null, null);
						if ((directState.getOnline_status() == 1) && (directState.getCharge_status() == 1) && (directState.getCable_status() == 1))
						{
							isBespeak = 1;
						}
						directState.setCharge_status(2);
						directState.setUser_pay_card(userCard);
						omsChargerStateDirectDao.updateObject(directState);
						break;
					case 2:
						OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
						alternateState_query.setPort_no(port_no);
						alternateState_query.setCharger_id(chargerId);
						alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
						if ((alternateState.getOnline_status() == 1) && (alternateState.getCharge_status() == 1) && (alternateState.getCable_status() == 1))
						{
							isBespeak = 1;
						}
						alternateState.setCharge_status(2);
						alternateState.setUser_pay_card(userCard);
						omsChargerStateAlternateDao.updateObject(alternateState);
						break;
					default:
						break;
				}

				log.debug("update status");

				if (chargerType == 1)
				{ // 1.2   保存到直流桩充电信息表中
					log.info("Receive response message from startCharge(chargerType is normal)");
					OmsChargerChargeDirectRecord omsChargerChargeDirectRecord = new OmsChargerChargeDirectRecord();
					String battery_type = map.get("battery_type");  //
					String battery_fac = map.get("battery_fac");  //
					// 134-142  电池组序号,不存入数据库
					String battery_volume = map.get("battery_volume");  //
					String battery_charge_times = map.get("battery_charge_times");  //
					String soc = map.get("soc");  //
					omsChargerChargeDirectRecord.setBattery_charge_times(battery_charge_times);
					omsChargerChargeDirectRecord.setBattery_fac(battery_fac);
					omsChargerChargeDirectRecord.setBattery_type(battery_type);
					omsChargerChargeDirectRecord.setBattery_volume(battery_volume);
					omsChargerChargeDirectRecord.setCharge_jrnl(chargeJrnl);
					omsChargerChargeDirectRecord.setCharger_id(chargerId);
					omsChargerChargeDirectRecord.setPort_no(port_no);
					omsChargerChargeDirectRecord.setSoc_start(soc);
					omsChargerChargeDirectRecord.setStart_time(now);
					omsChargerChargeDirectRecord.setStation_id(charger.getStation_id());
					omsChargerChargeDirectRecord.setUser_pay_card(userCard);
					omsChargerChargeDirectRecord.setValid_flag(1);
					omsChargerChargeDirectRecordDao.save(omsChargerChargeDirectRecord);
				}


				json.setCode("200");
				json.setMsg("success");
//				json.setCode(json.getCode().concat(":").concat(String.valueOf(notifyFlag))); // 设置通知标识
				log.debug(json);
			}
			else
			{
				json.setCode(responseCode);
				json.setMsg("Failed to start charger");
			}
			// 组装下发报文
			responseMsgHeader = "680000" + data.substring(6, 34) + "56" + data.substring(36, 50);
			responseMsgBody = "";
			log.debug("Send to charger ev3c0102StartChargeReturn = " + responseMsgHeader.concat(responseMsgBody));
			return StringUtil.getjsonCReturn(responseMsgHeader, responseMsgBody, "200", "ok");
		}
		catch (Exception e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
	}

	private JsonCommon<String> ev3c0103StartChargeReturn(Map<String, String> map) {
		String data = map.get("data");
		String chargerId,bespeakJrnl,responseMsgHeader,responseMsgBody,requestURL;
		JsonCommon<String> json = new JsonCommon<String>();
		OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord();
//		String[] header = StringUtil.getMessageHeader(data);
		chargerId = map.get("chargerId");
		Date now = new Date();
		OmsChargerStateDirect directState;
		OmsChargerStateAlternate alternateState;
		String charge_port = map.get("charge_port");  //充电口号
		int port_no = Integer.parseInt(charge_port, 2);
		String userCard = map.get("userCard");  //用户卡号
		String vin = map.get("vin");  //车辆识别码（VIN） 可选填（0xff为无效）
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query,null,null);
		if(charger==null||charger.getCharger_type()==null){
			json.setCode("400");
			json.setMsg("charger not found");
			responseMsgHeader =data.substring(0, 8)+OmsConstant.MsgResponseCodeEnum.SysError.value()+data.substring(14, 34)+ev3c_frameCode+data.substring(36,50);
			json.setPojo(responseMsgHeader);
			return json;
		}
		//查询桩是否被预约，如果没有预约，就不需要做关联。
		int chargerType = charger.getCharger_type();
		int isBespeak = 0;
		switch (chargerType) {//1--直流  2--交流  3--混合
		case 1:
			OmsChargerStateDirect directState_query =  new OmsChargerStateDirect();
			directState_query.setPort_no(port_no);
			directState_query.setCharger_id(chargerId);
			directState =  omsChargerStateDirectDao.findOneExample(directState_query,null,null);
			if((directState.getOnline_status()==1)&&(directState.getCharge_status()==1)&&(directState.getCable_status()==1)){
				isBespeak = 1;
			}
			directState.setCharge_status(2);
			omsChargerStateDirectDao.updateObject(directState);
			break;
		case 2:
			OmsChargerStateAlternate alternateState_query =  new OmsChargerStateAlternate();
			alternateState_query.setPort_no(port_no);
			alternateState_query.setCharger_id(chargerId);
			alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query,null,null);
			if((alternateState.getOnline_status()==1)&&(alternateState.getCharge_status()==1)&&(alternateState.getCable_status()==1)){
				isBespeak = 1;
			}
			alternateState.setCharge_status(2);
			omsChargerStateAlternateDao.updateObject(alternateState);
			break;
		default:
			break;
		}
		if(isBespeak == 1){//通过用户卡号、电桩地址、当前系统时间在预约开始时间和预约理论结束时间之间 来查询预约费用记录表
			OmsChargerBespeakBillRecord  bespeakBillRecord_query  = new OmsChargerBespeakBillRecord();
			bespeakBillRecord_query.setCharger_id(chargerId);
			bespeakBillRecord_query.setUser_pay_card(userCard);
			OmsChargerBespeakBillRecord  bespeakBillRecord = omsChargerBespeakBillRecordDao.findOneExample(bespeakBillRecord_query,null,null);
			if(bespeakBillRecord==null){//如果查询不到结果，就说明被另外的人预约了然后这个用户去充电
			}else{

				if((bespeakBillRecord.getValid_flag()==1)&&(now.compareTo(bespeakBillRecord.getStart_time())>=0)&&(now.compareTo(bespeakBillRecord.getEstimate_end_time())<=0)){
					//证明了之前的预约记录是这个人的而且在预约时间范围内
					bespeakJrnl = bespeakBillRecord.getBespeak_jrnl();
					billRecord.setBespeak_jrnl(bespeakJrnl);
				}
			}
		}
		//通过当前时间  + 桩地址 + 用户卡号 生成流水号
		String chargeJrnl =   chargerId +"0" + port_no + userCard + StringUtil.now14time();
		billRecord.setCharge_jrnl(chargeJrnl);
		billRecord.setCharger_id(chargerId);
		billRecord.setUser_pay_card(userCard);
		billRecord.setStation_id(charger.getStation_id());
		billRecord.setStart_time(now);
		billRecord.setStatus(1);
		billRecord.setPort_no(port_no);
		billRecord.setVIN(vin);
		billRecord.setValid_flag(1);
		billRecord.setChar_bill((float) 0);
		//线上卡是18808开头  线下卡是18806开头
		if(userCard.startsWith("18808")){
			billRecord.setOffline_is_pay(2);
		}else{
			billRecord.setOffline_is_pay(0);
		}
		omsChargerChargeBillRecordDao.save(billRecord);
		if(chargerType == 1){//1.3独有   保存到直流桩充电信息表中
			OmsChargerChargeDirectRecord omsChargerChargeDirectRecord = new OmsChargerChargeDirectRecord();
			String battery_type = map.get("battery_type");  //
			String battery_fac = map.get("battery_fac");  //
			String battery_volume = map.get("battery_volume");  //
			String battery_voltage = map.get("battery_voltage");  //
			String battery_charge_times = map.get("battery_charge_times");  //
			String battery_voltage_max = map.get("battery_voltage_max");  //
			String battery_current_max = map.get("battery_current_max");  //
			String battery_energy_total = map.get("battery_energy_total");  //
			String voltage_max = map.get("voltage_max");  //
			String battery_temperature_max = map.get("battery_temperature_max");  //
			String soc = map.get("soc");//
			String battery_voltage_total = map.get("battery_voltage_total");  //
			omsChargerChargeDirectRecord.setBattery_charge_times(battery_charge_times);
			omsChargerChargeDirectRecord.setBattery_current_max(battery_current_max);
			omsChargerChargeDirectRecord.setBattery_energy_total(battery_energy_total);
			omsChargerChargeDirectRecord.setBattery_fac(battery_fac);
			omsChargerChargeDirectRecord.setBattery_temperature_max(battery_temperature_max);
			omsChargerChargeDirectRecord.setBattery_type(battery_type);
			omsChargerChargeDirectRecord.setBattery_voltage(battery_voltage);
			omsChargerChargeDirectRecord.setBattery_voltage_max(battery_voltage_max);
			omsChargerChargeDirectRecord.setBattery_voltage_total(battery_voltage_total);
			omsChargerChargeDirectRecord.setBattery_volume(battery_volume);
			omsChargerChargeDirectRecord.setCharge_jrnl(chargeJrnl);
			omsChargerChargeDirectRecord.setCharger_id(chargerId);
			omsChargerChargeDirectRecord.setPort_no(port_no);
			omsChargerChargeDirectRecord.setSoc_start(soc);
			omsChargerChargeDirectRecord.setStart_time(now);
			omsChargerChargeDirectRecord.setStation_id(charger.getStation_id());
			omsChargerChargeDirectRecord.setUser_pay_card(userCard);
			omsChargerChargeDirectRecord.setValid_flag(1);
			omsChargerChargeDirectRecord.setVoltage_max(voltage_max);
			omsChargerChargeDirectRecordDao.save(omsChargerChargeDirectRecord);
		}
        responseMsgHeader =data.substring(0, 2)+"0000"+data.substring(6, 34)+ev3c_frameCode+data.substring(36,50);
        //TODO AS接口
//        String dzFun="&a=start_charge";
//        requestURL = StringUtil.dzAppURL+dzFun+"&dianzhuanghao="+charger.getQr_code()+"&user_pay_card="+userCard+"&start_time="+StringUtil.now14time()+"&dianzhanid="+charger.getStation_id();
//        StringUtil.httpGetRequest(requestURL);
        responseMsgBody ="";
//        String jsonStr =StringUtil.getjsonReturn(responseMsgHeader, responseMsgBody, code, msg);
		return StringUtil.getjsonCReturn(responseMsgHeader, responseMsgBody, "200", "ok");
	}

	@Override
	public JsonCommon<String> stopCharge(Map<String,String> map) throws Exception
	{
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		String data = map.get("data");
		if(protocol_type==null){
			protocol_type  = "1";
		}
		if(protocol_version==null){
			protocol_version  = "0103";
		}
		switch (protocol_type) {
		case "1":
			ev3c_frameCode = "12";
			switch (protocol_version) {
			case "0101":
				json = ev3c0101StopCharge(map, data);
				break;
			case "0102":
				json = ev3c0102StopCharge(map, data);
				break;
			case "0103":
				json = ev3c0103StopCharge(map, data);
				break;
			case "0201":
				json = ev3c0201StopCharge(map, data);
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		return json;
	}

	/**
	 * 针对0101或0102 版本协议
	 * 关闭充电执行流程如下:
	 * 1.判断当前枪口状态,如果为非充电中,则直接返回接口。
	 * 2.更新充电费用记录表(状态为已下发关闭充电:下发关闭充电中)
	 * 3.下发报文
     * 
     * 预约费用表状态:
   	 * 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)  2:电充满未结束(如未拔枪则是此状态)  3:关闭充电(已下发指令)  4:充电结束(桩回复充电结束)  5:已生成账单  6:已结算  7:已退款  8:充电失败
   	 * 
	 * @param map
	 * @param data
	 * @return JsonCommon<String>
	 */
	private JsonCommon<String> ev3c0101StopCharge(Map<String, String> map, String data) {
		log.info("Receive response message from stopCharge! curTime = " + new Date().getTime());
		String chargerId = map.get("chargerId");
		String userCard= map.get("userCard");
		String portNo= map.get("portNo");
		portNo = Ev3cEncapsulationServiceImpl.portNoWithMsg(portNo);
		portNo = portNo.length() == 1 ? "0".concat(portNo):portNo;
		String responseMsgHeader,responseMsgBody;
		String code_type = "12";
		String control_type = "04";
		String msg_charge_end_jrnl = serialGenerater.generateSerialNo14(); // StringUtil.now14time();
		responseMsgBody = portNo+control_type+userCard;
		responseMsgHeader ="68"+StringUtil.ev3cMsgBodyBin(responseMsgBody)+"01"+"000000"+"0001"+chargerId+code_type+msg_charge_end_jrnl;
		portNo = Ev3cEncapsulationServiceImpl.portNoWithDb(portNo);
		// 1.判断当前枪口状态,如果为非预约中,则直接返回接口
		// [判断该枪口状态,若为空闲状态可预约成功(预约采用独占试,考虑到并发,查询枪口状态和入库两个操作必须控制在同一把锁来处理,防止脏数据)]
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		int port_no = Integer.parseInt(portNo, 2);
		OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query, null, null);
		/** 0:空闲  1:预约  2:充电  3:故障  4:占用中(针对双枪单充等情况) 5:刷卡中  8:离线*/
		int chargeStatus = 0; // 当前桩,对应枪口状态
		int chargerType = 1; // 1:直流  2:交流  3:混合
		OmsChargerStateDirect directState = null; // 直流表信息
		OmsChargerStateAlternate alternateState = null; // 交流表信息
		Date now = new Date();
		String bespeakJrnl;
		OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord();
		OmsChargerChargeBillRecord billRecord_query = new OmsChargerChargeBillRecord();
		billRecord_query.setCharger_id(chargerId);
		billRecord_query.setStatus(1); // 1 充电中:已确认桩回复
		billRecord_query.setPort_no(port_no);
		billRecord_query.setValid_flag(1);
//		billRecord_query.setOffline_is_pay(2);// 0:线下未结算,1:线下已结算,2:线上未结算,3.线上已结算 
		billRecord_query.setUser_pay_card(userCard);
		billRecord = omsChargerChargeBillRecordDao.findOneExample(billRecord_query, "start_time", "desc");
		if (billRecord == null){
			log.info("charger :"+chargerId+" port_no:"+port_no +" not in charge status");
			json.setCode("400");
			json.setMsg("charger :"+chargerId+" port_no:"+port_no +" not in charge status");
			return json;
		}		
		
		// 2.1查询枪口当前状态
		if (charger.getCharger_type() != null) {
			chargerType = charger.getCharger_type();
			switch (chargerType) { // 1:直流  2:交流  3:混合
			case 1:
				OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
				directState_query.setPort_no(port_no);
				directState_query.setCharger_id(map.get("chargerId"));
				directState = (OmsChargerStateDirect) omsChargerStateDirectDao.findOneExample(directState_query, null, null);
				chargeStatus = directState.getCharge_status();
				log.info("chargeStatus = "+ chargeStatus);
				directState.setCharge_status(0); // 设置为空闲状态
				directState.setCharge_jrnl(null); // 下发报文充电开始流水号(报文开始充电流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20 0x15 0x05 0x10 0x21 0x45 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
				omsChargerStateDirectDao.updateObject(directState);
				break;
			case 2:
				OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
				alternateState_query.setPort_no(port_no);
				alternateState_query.setCharger_id(chargerId);
				alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
				chargeStatus = alternateState.getCharge_status();
				log.info("chargeStatus = "+ chargeStatus);
				alternateState.setCharge_status(0); // 设置为空闲状态
				alternateState.setCharge_jrnl(null); // 下发报文充电开始流水号(报文开始充电流水号,系统生成,:格式为:YYYY-MM-DD-HH-MI-SS加上四位序号 例如：0x20 0x15 0x05 0x10 0x21 0x45 0x34,0x00,0x00表示2015年5月10日21点击5分34秒第一个流水号(同一时刻自增))
				omsChargerStateAlternateDao.updateObject(alternateState);
				break;
			default:
				break;
			}
		}
		
		log.info("chargeStatus = " + chargeStatus);
		
		if (chargeStatus == 2) { // 当前桩,对应枪口状态为充电

			billRecord.setMsg_charge_end_jrnl(msg_charge_end_jrnl); // 设置充电结束流水号
			omsChargerChargeBillRecordDao.updateObject(billRecord); // 更新费用记录表

//			OmsChargerBespeakBillRecord bespeakBillRecord_query = new OmsChargerBespeakBillRecord();
//			bespeakBillRecord_query.setCharger_id(chargerId);
//			bespeakBillRecord_query.setUser_pay_card(userCard);
//			bespeakBillRecord_query.setPort_no(port_no);
//			bespeakBillRecord_query.setStatus(5); //预约状态:1:预约中  2:已预约  3:取消预约中  4:已取消预约  5:充电(流程1:1-2-3-4, 流程2:1-2-5)
//			billRecord_query.setValid_flag(1);
////			billRecord_query.setOffline_is_pay(2);// 0:线下未结算,1:线下已结算,2:线上未结算,3.线上已结算
//			OmsChargerBespeakBillRecord bespeakBillRecord = omsChargerBespeakBillRecordDao.findOneExample(bespeakBillRecord_query, "start_time","desc");
//			if (bespeakBillRecord == null) { // 没有预约直接来充电
//				log.info("no bespeakBillRecord record found");
//			} else { // 预约转充电
//				if ((bespeakBillRecord.getValid_flag() == 1)
//						&& (now.compareTo(bespeakBillRecord.getStart_time()) >= 0)
//						&& userCard.equals(billRecord.getUser_pay_card())) {
//					log.info("update bill record");
//					// && (now.compareTo(bespeakBillRecord.getEstimate_end_time()) <= 0)){
//					// 证明了之前的预约记录是这个人的而且在预约时间范围内
////					bespeakJrnl = bespeakBillRecord.getBespeak_jrnl();
////					billRecord.setBespeak_jrnl(bespeakJrnl);
////					billRecord.setStatus(3); // 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)  2:电充满未结束(如未拔枪则是此状态)  3:关闭充电(已下发指令)  4:充电结束:桩回复充电结束)  5:已生成账单  6:已结算  7:已退款  8:充电失败
////					bespeakBillRecord.setStatus(5); // 预约状态:1:预约中  2:已预约  3:取消预约中  4:已取消预约  5:充电(流程1:1-2-3-4, 流程2:1-2-5)
////					omsChargerBespeakBillRecordDao.updateObject(bespeakBillRecord); // 更新预约表状态
//				} else { // 关闭充电卡号不是预约卡号,记录日志(异常数据)
//					log.info("userCard: "+userCard+" not charge in charger, StopCharge fail!  "+chargerId);
//					json.setCode("400");
//					json.setMsg("userCard: "+userCard+" not charge in charger "+chargerId);
//					return json;
//				}
//			}
			
//			// 3.根据卡号判断,如果为APP卡号,则调用App AppChargeNotifyParam通知;
//			// 如果为企业卡号,则调用企业回调URL:参考主服务器login(用户登录使用)接口。
//			// 先查询oms_oper_list中的notifyUrl,如果没有,就不管了。
//			// 企业用户登录流程:先访问主服务器,成功后把相应的信息存入oms_oper_list表中。
//			// 线上卡是18808开头(08 线上卡),线下卡是18806开头(06 现金卡),05 身份认证卡
//			if (userCard.startsWith("18808") && !userCard.substring(0, 9).equals("188089999")) { // APP卡号
//				log.info("Receive response message from stopCharge(billRecord_query)");
//				// 通知appServer start
//				log.info("Receive response message from stopCharge(AppChargeNotifyParam)");
//				AppChargeNotifyParam obj = new AppChargeNotifyParam();
//				obj.setAction(AppServerConstant.CHARGE_NOTIFY_ACTION_END_CHARGE); // 结束充电
//				if (billRecord.getBespeak_jrnl() == null || "".equals(billRecord.getBespeak_jrnl())) {
//					obj.setChargeType("0"); // 非预约充电
//				} else {
//					obj.setChargeType("1"); // 预约充电
//				}
//				obj.setStationName(charger.getStation_name());
//				obj.setSerialNo(charger.getSerial_no());
//				obj.setPlugNo(String.valueOf(billRecord_query.getPort_no()));
//				obj.setChargerId(chargerId);
//				obj.setUserCard(userCard);
//				obj.setChargeSn(billRecord.getCharge_jrnl());
//				obj.setStartTime(billRecord.getStart_time().toString());
//				json.setPojo(billRecord.toString());
//				json = systemAppServerRpcClient.chargeNotify(obj);
//				// 通知appServer end
//				if (json.getCode().equals("200")) {
//					json.setMsg("chargerId " + chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> result:chargeNotify success!");
//					log.debug("chargerId " + chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> result:chargeNotify success!");
//				} else {
//					json.setMsg("chargerId " + chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> result:chargeNotify fail!");
//					log.error("chargerId " + chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> result:chargeNotify fail!");
//				}
//				// 通知appServer end
//			} else { // TODO peizhide 预留第三方接口
//				log.info("3");
//			}
			
			// 3.下发报文
			try {
				log.info("Send message to stopCharge sendNoWait! curTime = " + new Date().getTime());
				ev3cMessageService.sendNoWait(responseMsgHeader+responseMsgBody, chargerId);
			} catch (RetryFailException e) {
				json.setCode("400");
				json.setMsg("chargerId "+ chargerId +" stopCharge sendNoWait fail "+e.getMessage());
				log.error("chargerId " + chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopCharge -> result:stopCharge sendNoWait fail!" + e.getMessage());
				return json;
			} catch (CreateConnectionFailException e) {
				json.setCode("400");
				json.setMsg("chargerId "+ chargerId +" stopCharge sendNoWait fail "+e.getMessage());
				log.error("chargerId " + chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopCharge -> result:stopCharge sendNoWait fail!" + e.getMessage());
				return json;
			} catch (DuplicateInstructionException e) {
				log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
				json.setCode("400");
				json.setMsg("chargerId "+ chargerId +" stopCharge sendNoWait fail "+e.getMessage());
				log.error("chargerId " + chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopCharge -> result:stopCharge sendNoWait fail!" + e.getMessage());
				return json;
			}
			
			json.setCode("200");
			json.setMsg("stopCharge sendNoWait success!");
			json.setPojo(ev3c_msgHeader + ev3c_msgBody);
			log.debug("chargerId "+ chargerId + " Class:OmsBespeakServiceImpl -> method:ev3c0101CancelBespeak -> result:cancelBespeak sendSocket success!");
		} else { // 否则:接口直接返回关闭充电失败
			json.setCode(OmsConstant.ErrorCodeEnum.ChargeResultCloseChargerFail.value());
			json.setMsg("chargerId " + chargerId + "userCard " + userCard + " ev3c0101Bespeak:StopCharge The charger close fail!"); // 带卡号
			log.error("chargerId " + chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopCharge -> result:The charger close fail!");
		}
		return json;
	}
	private JsonCommon<String> ev3c0102StopCharge(Map<String, String> map, String data) {
		return ev3c0101StopCharge(map, data);
	}

	private JsonCommon<String> ev3c0103StopCharge(Map<String, String> map, String data) {
		return ev3c0101StopCharge(map, data);
	}

	private JsonCommon<String> ev3c0201StopCharge(Map<String, String> map, String data) throws Exception
	{
		log.info(map);
		String chargeStartSerialNumber = map.get("chargeStartSerialNumber");
//		String chargerId = map.get("chargerId");
//		String userCard = map.get("userCard");
//		String portNo = map.get("portNo");


		OmsChargerChargeBillRecord billRecord_query = new OmsChargerChargeBillRecord();
		billRecord_query.setMsg_charge_jrnl(chargeStartSerialNumber);
		OmsChargerChargeBillRecord billRecord = omsChargerChargeBillRecordDao.findOneExample(billRecord_query, null, null);
		if(billRecord == null)
			throw new BizException("Bill record not found");
		log.info(billRecord.getCharge_jrnl());

		String userCard = billRecord.getUser_pay_card();
		String chargerId = billRecord.getCharger_id();
		Integer portNo = billRecord.getPort_no();

		String ev3c_msgBody = userCard + chargeStartSerialNumber;
		String frameCode = "14";
		String encryption = "00";

		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger.getCharger_type() == null)
			throw new BizException ("charger not found");
		log.info(charger.getCharger_id());


		int chargerType = charger.getCharger_type();
		String msg = messageWrapper.wrapSendingMsg(ev3c_msgBody, frameCode, chargerId, String.valueOf(chargerType), String.valueOf(portNo), encryption);
		String end_jrnl = msg.substring(32, 50);


		billRecord.setMsg_charge_end_jrnl(end_jrnl);
		billRecord.setStatus(OmsConstant.ChargingBillStatus.NotifyStopCharging);
		billRecord.setEnd_time(new Date());
		omsChargerChargeBillRecordDao.updateObject(billRecord);


		try
		{
			ev3c2MessageService.sendNoWait(msg, chargerId);
		}
		catch (RetryFailException e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
		catch (CreateConnectionFailException e)
		{
			log.error(e.getMessage(), e);
			throw e;
		}
		JsonCommon<String> json = new JsonCommon<>();
		json.setCode("200");
		json.setMsg(chargerId + " " + userCard + "stopCharge sendSocket success");
		json.setPojo(msg);
		return json;
	}
	@Override
	public JsonCommon<String> stopChargeReturn(Map<String,String> map) {
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		switch (protocol_type) {
		case "1":
			ev3c_frameCode = "12";
			switch (protocol_version) {
			case "0101":
				json = ev3c0101StopChargeReturn(map);
				break;
			case "0102":
				json = ev3c0102StopChargeReturn(map);
				break;
			case "0103":
				json = ev3c0103StopChargeReturn(map);
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		return json;
	}

	/**
	 * 针对0101或0102 版本协议
	 * 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调)
	 * 2.更新充电费用记录表(状态为已回复关闭充电:已关闭)
	 * 3.更新直流或交流表信息  
	 * 4.App ChargeNotifyParam通知,通知已经关闭
	 * 
     * 预约费用表状态:
   	 * 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)  2:电充满未结束(如未拔枪则是此状态)  3:关闭充电(已下发指令)  4:充电结束(桩回复充电结束)  5:已生成账单  6:已结算  7:已退款  8:充电失败
   	 * 
	 * @param map
	 * @return JsonCommon<String>
	 */
	private JsonCommon<String> ev3c0101StopChargeReturn(Map<String, String> map) {
		String chargerId,responseMsgHeader,responseMsgBody,code,msg;
		
		JsonCommon<String> json = new JsonCommon<String>();
		Date now = new Date();
		String data = map.get("data");
		chargerId = map.get("chargerId");
        String charge_port = map.get("portNo");
        charge_port = Ev3cEncapsulationServiceImpl.portNoWithDb(charge_port); 
        int port_no = Integer.parseInt(charge_port, 2);
		String userCard = map.get("userCard");  //用户卡号
		String responseCode= data.substring(8, 14); // 获取响应码
		OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord();
		
		responseMsgBody ="";
		responseMsgHeader =data.substring(0, 2)+"0000"+data.substring(6, 34)+"57"+data.substring(36,50);
		// 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调);否则进入第二步。
		if (OmsBespeakServiceImpl.checkChargerReplyMessageStatus(responseCode)) { // 正常
			OmsCharger charger_query = new OmsCharger();
			charger_query.setCharger_id(chargerId);
			charger_query.setPort_no(port_no);
			OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query, null, null);
			
			// 报文中需要有直流和交流的区别,如果是为了中新用的,就应该是oms_charger_state_direct[直流充电桩状态表]
			if (charger.getCharger_type() != null) {
				int chargerType = charger.getCharger_type();
				switch (chargerType) { // 1:直流  2:交流  3:混合
				case 1:
					OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
					directState_query.setPort_no(port_no);
					directState_query.setCharger_id(map.get("chargerId"));
					OmsChargerStateDirect directState = (OmsChargerStateDirect) omsChargerStateDirectDao.findOneExample(directState_query, null, null);
					directState.setCharge_status(0);
					directState.setOnline_status(1);
					omsChargerStateDirectDao.updateObject(directState);
					break;
				case 2:
					OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
					alternateState_query.setPort_no(port_no);
					alternateState_query.setCharger_id(chargerId);
					OmsChargerStateAlternate alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
					alternateState.setCharge_status(0);
					alternateState.setOnline_status(1);
					omsChargerStateAlternateDao.updateObject(alternateState);
					break;
				default:
					break;
				}
			}

			// 2.处理费用,更新费用记录表(状态为已关闭)
			//更新充电费用记录表
			OmsChargerChargeBillRecord billRecord_query = new OmsChargerChargeBillRecord();
			billRecord_query.setCharger_id(chargerId);
			billRecord_query.setStation_id(charger.getStation_id());
			billRecord_query.setStatus(1);
			billRecord_query.setPort(port_no);
			billRecord_query.setValid_flag(1);
//			billRecord_query.setOffline_is_pay(0);

			if (userCard.startsWith("18808")) {
				billRecord_query.setOffline_is_pay(2);
			} else {
				billRecord_query.setOffline_is_pay(0);
			}

			billRecord = omsChargerChargeBillRecordDao.findOneExample(billRecord_query,"start_time","desc");
			if(billRecord==null){
				billRecord = new OmsChargerChargeBillRecord();
				billRecord.setPort_no(port_no);
			}
			billRecord.setEnd_time(now);
			//线上卡是18808开头  线下卡是18806开头
			if (userCard.startsWith("18808")) {
				billRecord.setOffline_is_pay(2);
			} else {
				billRecord.setOffline_is_pay(0);
			}
			billRecord.setStatus(4); // 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)
										// 2:电充满未结束(如未拔枪则是此状态)
										// 3:关闭充电(已下发指令) 4:充电结束 (桩回复充电结束 )
										// 5:已生成账单 6:已结算 7:已退款 8:充电失败
			omsChargerChargeBillRecordDao.updateObject(billRecord);

			// 3.根据卡号判断,如果为APP卡号,则调用App AppChargeNotifyParam通知;
			// 如果为企业卡号,则调用企业回调URL:参考主服务器login(用户登录使用)接口。
			// 先查询oms_oper_list中的notifyUrl,如果没有,就不管了。
			// 企业用户登录流程:先访问主服务器,成功后把相应的信息存入oms_oper_list表中。
			// 线上卡是18808开头(08 线上卡),线下卡是18806开头(06 现金卡),05 身份认证卡
//			if (userCard.startsWith("18808") && !userCard.substring(0, 9).equals("188089999")) { // APP卡号
//				log.debug("chargerId "+ chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn ->通知app");
//                try {
//                	// 通知appServer start
//    		        AppChargeNotifyParam obj = new AppChargeNotifyParam();
//    		 		obj.setAction(AppServerConstant.CHARGE_NOTIFY_ACTION_END_CHARGE); // 结束充电
//    		 		if (billRecord_query.getBespeak_jrnl() == null || "".equals(billRecord.getBespeak_jrnl())) {
//    		 			obj.setChargeType("0"); // 非预约充电
//    				} else {
//    					obj.setChargeType("1"); // 预约充电
//    				}
//    		 		obj.setStationName(charger.getStation_name());
//    		 		obj.setSerialNo(charger.getSerial_no());
//    		 		obj.setPlugNo(String.valueOf(billRecord.getPort_no()));
//    		 		obj.setChargerId(chargerId);
//    		 		obj.setUserCard(userCard);
//    		 		obj.setChargeSn(billRecord.getCharge_jrnl());
//    		 		obj.setStartTime(billRecord.getStart_time().toString());
//    		 		json.setPojo(billRecord.toString());
//    		 		json = systemAppServerRpcClient.chargeNotify(obj);
//    		     	// 通知appServer end
//    				if (json.getCode().equals("200")) {
//    					json.setMsg("chargerId "+ chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> result:chargeNotify success!");
//    					log.debug("chargerId "+ chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> result:chargeNotify success!");
//    				} else {
//    					json.setMsg("chargerId "+ chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> result:chargeNotify fail!");
//    					log.error("chargerId "+ chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> result:chargeNotify fail!");
//    				}
//				} catch (Exception e) {
//					log.error(e.getMessage(), e);
//					json.setMsg("chargerId "+ chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> result:chargeNotify fail!");
//					log.error("chargerId "+ chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> result:chargeNotify fail!");
//				}
//
//				// 通知appServer end
//				log.debug("chargerId "+ chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> 通知app end");
//
//			} else { // TODO peizhide 预留第三方接口
//			}
		} else { // 入库oms_charger_error_record[故障记录表]
//			OmsChargerErrorRecord record = new OmsChargerErrorRecord();
//			record.setCharger_id(chargerId);
//			record.setError_code(responseCode);
//			record.setError_msg("StopCharge fault");
//			record.setStatus(0); // 0:未处理,1:已处理
//			record.setValid_flag(1);
//			record.setCreate_oper_id("000");
//			record.setCreate_time(new Date());
//			omsChargerErrorRecordService.add(record);
//			
//			json.setCode(OmsConstant.ErrorCodeEnum.StopChargeResultConnectionException.value());
//			json.setMsg("chargerId " + chargerId + "userCard " + userCard + " ev3c0101StopChargeReturn: stopChargeReturn connection status fail!"); // 带卡号
//			log.error("chargerId " + chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> result:stopChargeReturn connection status fail!");
		}
        
        code = json.getCode();
        msg = json.getMsg();
		log.debug("chargerId "+ chargerId + " Class:OmsChargeServiceImpl -> method:ev3c0101StopChargeReturn -> 22");

		return StringUtil.getjsonCReturn(responseMsgHeader, responseMsgBody, code, msg);
	}

	/**
	 * 针对0102版本协议
	 * 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调)
	 * 2.更新充电费用记录表(状态为已回复关闭充电:已关闭)
	 * 3.更新直流或交流表信息  
	 * 4.App ChargeNotifyParam通知,通知已经关闭
	 * 
     * 预约费用表状态:
   	 * 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)  2:电充满未结束(如未拔枪则是此状态)  3:关闭充电(已下发指令)  4:充电结束(桩回复充电结束)  5:已生成账单  6:已结算  7:已退款  8:充电失败
   	 * 
	 * @param map
	 * @return JsonCommon<String>
	 */
	private JsonCommon<String> ev3c0102StopChargeReturn(Map<String, String> map) {
		log.info("Receive response message from stopChargeReturn");
		String chargerId,responseMsgHeader,responseMsgBody,code,msg;
		JsonCommon<String> json = new JsonCommon<String>();
		json.setCode("200");
		Date now = new Date();
		String data = map.get("data");
		chargerId = map.get("chargerId");
        String charge_port = data.substring(50, 52);
        charge_port = Ev3cEncapsulationServiceImpl.portNoWithDb(charge_port);
        int port_no = Integer.parseInt(charge_port, 2);
		String userCard = map.get("userCard");  //用户卡号
		String responseCode= data.substring(8, 14); // 获取响应码
		OmsChargerChargeBillRecord billRecord = new OmsChargerChargeBillRecord();
		
		responseMsgHeader =data.substring(0, 2)+"0000"+data.substring(6, 34)+"57"+data.substring(36,50);
        responseMsgBody ="";
        
        // 1.判断回复报文中是否为正常返回,如果响应码不为000000,则做相应处理(记录入故障记录表,再回调);否则进入第二步。
 		if (OmsBespeakServiceImpl.checkChargerReplyMessageStatus(responseCode)) { // 正常
 			log.info("Receive response message from stopChargeReturn(responseCode is normal)");
 			OmsCharger charger_query = new OmsCharger();
 			charger_query.setCharger_id(chargerId);
 			charger_query.setPort_no(port_no);
 			OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query, null, null);
 			
 			// 报文中需要有直流和交流的区别,如果是为了中新用的,就应该是oms_charger_state_direct[直流充电桩状态表]
 			if (charger.getCharger_type() != null) {
 				int chargerType = charger.getCharger_type();
 				switch (chargerType) { // 1:直流  2:交流  3:混合
 				case 1:
 					OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
 					directState_query.setPort_no(port_no);
 					directState_query.setCharger_id(map.get("chargerId"));
 					OmsChargerStateDirect directState = (OmsChargerStateDirect) omsChargerStateDirectDao.findOneExample(directState_query, null, null);
 					directState.setCharge_status(0);
 					directState.setOnline_status(1);
 					directState.setUser_pay_card(null);
 					omsChargerStateDirectDao.updateObject(directState);
 					break;
 				case 2:
 					OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
 					alternateState_query.setPort_no(port_no);
 					alternateState_query.setCharger_id(chargerId);
 					OmsChargerStateAlternate alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
 					alternateState.setCharge_status(0);
 					alternateState.setOnline_status(1);
 					alternateState.setUser_pay_card(null);
 					omsChargerStateAlternateDao.updateObject(alternateState);
 					break;
 				default:
 					break;
 				}
 			}
 			
 			// 2.1处理费用,更新费用记录表(状态为已关闭)
			//更新充电费用记录表
			OmsChargerChargeBillRecord billRecord_query = new OmsChargerChargeBillRecord();
			billRecord_query.setCharger_id(chargerId);
			billRecord_query.setStation_id(charger.getStation_id());
			// billRecord_query.setStatus(4); // 由于自动充满导致没有更新该状态
			billRecord_query.setPort_no(port_no);
			billRecord_query.setValid_flag(1);
			//if (OmsBespeakServiceImpl.checkUserCardType(userCard) == 1) { // 1:app 
			if (userCard.startsWith("18808")) {
				billRecord_query.setOffline_is_pay(2);
			} else {
				billRecord_query.setOffline_is_pay(0);
			}
			billRecord_query.setUser_pay_card(userCard);
			boolean flag = true; // true:更新;false:插入
			billRecord = omsChargerChargeBillRecordDao.findOneExample(billRecord_query,"start_time","desc");
			if (billRecord == null){
				flag = false;
				billRecord = new OmsChargerChargeBillRecord();
				billRecord.setPort_no(port_no);
				String charge_jrnl = chargerId + String.format("%02d", port_no) + serialGenerater.generateSerialNo();
				billRecord.setCharge_jrnl(charge_jrnl);
				billRecord.setCharger_id(chargerId);
			} else {
				String msg_charge_end_jrnl = serialGenerater.generateSerialNo14(); // StringUtil.now14time();
				billRecord.setMsg_charge_end_jrnl(msg_charge_end_jrnl);
			}
			billRecord.setEnd_time(now);
			//线上卡是18808开头  线下卡是18806开头
			if (userCard.startsWith("18808")) {
				billRecord.setOffline_is_pay(2);
			} else {
				billRecord.setOffline_is_pay(0);
			}
			billRecord.setEnd_time(now);//由于报文中没有结束时间，所以此处用系统时间 
			billRecord.setCreate_time(now);
			billRecord.setStatus(4); // 0:开启充电(已下发指令未回复) 1:充电中(已确认桩回复)
										// 2:电充满未结束(如未拔枪则是此状态)
										// 3:关闭充电(已下发指令) 4:充电结束 (桩回复充电结束 )
										// 5:已生成账单 6:已结算 7:已退款 8:充电失败
			if (flag) { // 更新
				omsChargerChargeBillRecordDao.updateObject(billRecord);
			} else { // 插入
				omsChargerChargeBillRecordDao.save(billRecord);
			}
			
			// 3.根据卡号判断,如果为APP卡号,则调用App AppChargeNotifyParam通知;
			// 如果为企业卡号,则调用企业回调URL:参考主服务器login(用户登录使用)接口。
			// 先查询oms_oper_list中的notifyUrl,如果没有,就不管了。
			// 企业用户登录流程:先访问主服务器,成功后把相应的信息存入oms_oper_list表中。
			// 线上卡是18808开头(08 线上卡),线下卡是18806开头(06 现金卡),05 身份认证卡
		} else { // 入库oms_charger_error_record[故障记录表]
		}
        code = json.getCode();
        msg = json.getMsg();
		return StringUtil.getjsonCReturn(responseMsgHeader, responseMsgBody, code, msg);
	}

	private JsonCommon<String> ev3c0103StopChargeReturn(Map<String, String> map) {
		return ev3c0102StopChargeReturn(map);
	}

	@Override
	public JsonCommon<String> restartCharger(Map<String, String> map) {
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		if(protocol_type==null){
			protocol_type  = "1";
		}
		if(protocol_version==null){
			protocol_version  = "0103";
		}
		switch (protocol_type) {
		case "1":
			ev3c_frameCode = "18";
//			json.setCode("200");
//			json.setMsg("ok");
//			json.setPojo(null);
			switch (protocol_version) {
			case "0101":
				json = ev3c0101RestartCharger(map);
				break;
			case "0102":
				json = ev3c0101RestartCharger(map);
				break;
			case "0103":
				json = ev3c0101RestartCharger(map);
				break;
			case "0201":
				json = ev3c2RestartCharger(map);
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		return json;
	}

	private JsonCommon<String> ev3c2RestartCharger(Map<String, String> map)
	{
		JsonCommon<String> json = new JsonCommon<>();
		String chargerId = map.get("chargerId");

		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger.getCharger_type() == null)
		{
			log.error("charger not found");
			json.setCode("400");
			json.setMsg("charger not found");
			return json;
		}

		int chargerType = charger.getCharger_type();

		String body = "";
		String frameCode = "16";
		String encryption = "00";
		String portNo = "0";
		String msg = messageWrapper.wrapSendingMsg(body, frameCode, chargerId, String.valueOf(chargerType), portNo, encryption);
		try
		{
			ev3cMessageService.sendNoWait(msg, chargerId);
			json.setCode("200");
			json.setMsg("chargerId " + chargerId + " restart Charge successful ");
		}
		catch (RetryFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " restart sendSocket fail " + e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			log.error(e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " startCharge sendSocket fail " + e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId " + chargerId + " startCharge sendSocket fail " + e.getMessage());
			return json;
		}
		return json;
	}

	private JsonCommon<String> ev3c0101RestartCharger(Map<String, String> map) {
//		JsonCommon<String> json = new JsonCommon<String>();
//		String data = map.get("data");
		String chargerId = map.get("chargerId");
//		OmsCharger charger_query = new OmsCharger();
//		charger_query.setCharger_id(chargerId);
//		OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query,null,null);
//		int chargerType = charger.getCharger_type();
//		switch (chargerType) {//1--直流  2--交流  3--混合
//		case 1:
//			OmsChargerStateDirect directState_query =  new OmsChargerStateDirect();
//			directState_query.setCharger_id(chargerId);
//			List<OmsChargerStateDirect> directStateList =  omsChargerStateDirectDao.findExample(directState_query, null, null, null, null);
//			for(OmsChargerStateDirect chargerTemp :directStateList){
//				chargerTemp.setOnline_status(0);
//				omsChargerStateDirectDao.updateObject(chargerTemp);
//			}
//			break;
//		case 2:
//			OmsChargerStateAlternate alternateState_query =  new OmsChargerStateAlternate();
//			alternateState_query.setCharger_id(chargerId);
//			List<OmsChargerStateAlternate> alternateStateList =   omsChargerStateAlternateDao.findExample(alternateState_query, null, null, null, null);
//			for(OmsChargerStateAlternate chargerTemp :alternateStateList){
//				chargerTemp.setOnline_status(0);
//				omsChargerStateAlternateDao.updateObject(chargerTemp);
//			}
//			break;
//		default:
//			break;
//		}
		ev3c_msgBody ="";
		ev3c_msgHeader = "68"+"0000"+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		try {
			ev3cMessageService.sendNoWait(ev3c_msgHeader+ev3c_msgBody, chargerId);
		} catch (RetryFailException e) {
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId "+chargerId+" restart sendSocket fail "+e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId "+ chargerId +" startCharge sendSocket fail "+e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId "+ chargerId +" startCharge sendSocket fail "+e.getMessage());
			return json;
		}
		return StringUtil.getjsonCReturn(ev3c_msgHeader, ev3c_msgBody, "200", "ok");
	}

	@Override
	public JsonCommon<String> restartChargerReturn(Map<String, String> map) {
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		switch (protocol_type) {
		case "1":
			ev3c_frameCode = "19";
//			json.setCode("200");
//			json.setMsg("ok");
//			json.setPojo(null);
			switch (protocol_version) {
			case "0101":
				json = ev3c0101RestartChargerReturn(map);
				break;
			case "0102":
				json = ev3c0101RestartChargerReturn(map);
				break;
			case "0103":
				json = ev3c0101RestartChargerReturn(map);
				break;
			case "0201":
				json = ev3c0101RestartChargerReturn(map);
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		return json;
	}

	private JsonCommon<String> ev3c0101RestartChargerReturn(Map<String, String> map) {
//		JsonCommon<String> json = new JsonCommon<String>();
//		String data = map.get("data");
		String chargerId = map.get("chargerId");
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query,null,null);
		int chargerType = charger.getCharger_type();
		switch (chargerType) {//1--直流  2--交流  3--混合
		case 1:
			OmsChargerStateDirect directState_query =  new OmsChargerStateDirect();
			directState_query.setCharger_id(chargerId);
			List<OmsChargerStateDirect> directStateList =  omsChargerStateDirectDao.findExample(directState_query, null, null, null, null);
			for(OmsChargerStateDirect chargerTemp :directStateList){
				chargerTemp.setOnline_status(0);
//				chargerTemp.setCharge_status(8);
				omsChargerStateDirectDao.updateObject(chargerTemp);
			}
			break;
		case 2:
			OmsChargerStateAlternate alternateState_query =  new OmsChargerStateAlternate();
			alternateState_query.setCharger_id(chargerId);
			List<OmsChargerStateAlternate> alternateStateList =   omsChargerStateAlternateDao.findExample(alternateState_query, null, null, null, null);
			for(OmsChargerStateAlternate chargerTemp :alternateStateList){
				chargerTemp.setOnline_status(0);
//				chargerTemp.setCharge_status(8);
				omsChargerStateAlternateDao.updateObject(chargerTemp);
			}
			break;
		default:
			break;
		}
//		ev3c_msgBody ="";
//		ev3c_msgHeader = "68"+"0000"+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		return StringUtil.getjsonCReturn(ev3c_msgHeader, ev3c_msgBody, "200", "chargerId "+chargerId+" restart ok");
	}

	@Override
	public JsonCommon<String> updateFirmware(Map<String, String> map) {
		protocol_type = map.get("protocol_type");
		protocol_version = map.get("protocol_version");
		if(protocol_type==null){
			protocol_type  = "1";
		}
		if(protocol_version==null){
			protocol_version  = "0103";
		}
		switch (protocol_type) {
		case "1":
			ev3c_frameCode = "1A";
//			json.setCode("200");
//			json.setMsg("ok");
//			json.setPojo(null);
			switch (protocol_version) {
			case "0101":
				break;
			case "0102":
				break;
			case "0103":
				json = ev3c0103UpdateFirmware(map);
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
		return json;
	}

	private JsonCommon<String> ev3c0103UpdateFirmware(Map<String, String> map) {
		String chargerId = map.get("chargerId");
		String software_version_before = null;
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		//通过chargerId查询software_version_before
		OmsCharger charger = (OmsCharger) omsChargerDao.findOneExample(charger_query,null,null);
		if((charger!=null)&&(charger.getSoftware_version()!=null)){
			software_version_before = charger.getSoftware_version();
		}
		String software_version_after  = map.get("software_version_after");
		String login_oper_id = map.get("login_oper_id");
		String download_ip =  map.get("download_ip");//需要转成bin
		String download_port =  map.get("download_port");//需要转成bin
		String software_identifier =  map.get("software_identifier");
		String download_time =  map.get("download_time");//例如：0x20 0x15 0x05 0x10 0x13 0x20 0x11,表示2015年5月10日13时20分11秒
		String retry_interval =  map.get("retry_interval");//重试间隔（秒）//需要转成bin
		String retry_times =  map.get("retry_times");//超时次数  需要转成bin
		download_ip = StringUtil.ip2HexStr(download_ip);
		download_port = Integer.toHexString(Integer.valueOf(download_port));
		if(StringUtil.isBlank(retry_interval)){
			retry_interval = "0A";//10秒
		}else{
			retry_interval = StringUtil.float10to16ByParamDesc(retry_interval, 1, 2);
		}
		if(StringUtil.isBlank(retry_times)){
			retry_times = "03";//3次
		}else{
			retry_times = StringUtil.float10to16ByParamDesc(retry_times, 1, 2);
		}
		Date now = new Date();
		ev3c_msgBody = download_ip+download_port+software_identifier+download_time+retry_interval;
		ev3c_msgHeader = "68"+StringUtil.ev3cMsgBodyBin(ev3c_msgBody)+"01"+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		try {
			ev3cMessageService.sendNoWait(ev3c_msgHeader+ev3c_msgBody, chargerId);
			OmsChargerSoftwareRefresh omsChargerSoftwareRefresh;
			OmsChargerSoftwareRefresh omsChargerSoftwareRefresh_query = new OmsChargerSoftwareRefresh();
			omsChargerSoftwareRefresh_query.setCharger_id(chargerId);
			omsChargerSoftwareRefresh = omsChargerSoftwareRefreshDao.findOneExample(omsChargerSoftwareRefresh_query, null, null);
			if(omsChargerSoftwareRefresh==null){
				omsChargerSoftwareRefresh = new OmsChargerSoftwareRefresh();
				omsChargerSoftwareRefresh.setCharger_id(chargerId);
				omsChargerSoftwareRefresh.setAdditional_data(software_identifier);
				omsChargerSoftwareRefresh.setCreate_oper_id(login_oper_id);
				omsChargerSoftwareRefresh.setCreate_time(now);
				omsChargerSoftwareRefresh.setUpdate_oper_id(login_oper_id);
				omsChargerSoftwareRefresh.setUpdate_time(now);
				omsChargerSoftwareRefresh.setSoftware_version_before(software_version_before);
				omsChargerSoftwareRefresh.setSoftware_version_after(software_version_after);
				omsChargerSoftwareRefreshDao.save(omsChargerSoftwareRefresh);
			}else{
				omsChargerSoftwareRefresh.setUpdate_oper_id(login_oper_id);
				omsChargerSoftwareRefresh.setUpdate_time(now);
				omsChargerSoftwareRefresh.setSoftware_version_after(software_version_after);
				omsChargerSoftwareRefreshDao.updateObject(omsChargerSoftwareRefresh);
			}
		} catch (RetryFailException e) {
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId "+chargerId+" updateFirmware  sendSocket fail "+e.getMessage());
			return json;
		}
		catch (CreateConnectionFailException e)
		{
			e.printStackTrace();
			json.setCode("400");
			json.setMsg("chargerId "+ chargerId +" startCharge sendSocket fail "+e.getMessage());
			return json;
		} catch (DuplicateInstructionException e) {
			log.error("Send message failure, repeat instruction! e = " + e.getMessage(), e);
			json.setCode("400");
			json.setMsg("chargerId "+ chargerId +" startCharge sendSocket fail "+e.getMessage());
			return json;
		}
		json.setCode("200");
		json.setMsg("chargerId "+chargerId+" updateFirmware sendSocket success");
		return json;
	}

	@Override
	public JsonCommon<String> ev3c2startChargeReturn(Map<String, String> map) throws Exception
	{
		log.info(map);
		//写入后台异常
		String	msgResponseCode = map.get("msgResponseCode");
		log.info(msgResponseCode);
		if(!msgResponseCode.equals(OmsConstant.MsgResponseCodeEnum.Normal.value()))
		{
			log.error("charger response a non-normal code");
			throw new BizException("charger response a non-normal code");
		}

		OmsChargerChargeBillRecord billRecord_query = new OmsChargerChargeBillRecord();
		billRecord_query.setMsg_charge_jrnl(map.get("omsSerialNumber"));
		log.info(map.get("omsSerialNumber"));
		OmsChargerChargeBillRecord billRecord = omsChargerChargeBillRecordDao.findOneExample(billRecord_query, null, null);
		if (billRecord == null)
			throw new BizException("charger oms Serial Number not found");

		String chargerId = billRecord.getCharger_id();

		log.info(chargerId);
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query,null,null);
		if(charger==null||charger.getCharger_type()==null)
		{
			log.error("charger not found");
			throw new BizException("charger not found");
		}


		billRecord.setStatus(OmsConstant.ChargingBillStatus.Charging);//1 充电中 ：已确认桩回复；
		omsChargerChargeBillRecordDao.updateObject(billRecord);

		if(StringUtils.isNotEmpty(billRecord.getBespeak_jrnl()))
		{
			log.info("Reservation number is not empty");
			OmsChargerBespeakBillRecord bespeakBillRecord_query = new OmsChargerBespeakBillRecord();
			bespeakBillRecord_query.setBespeak_jrnl(billRecord.getBespeak_jrnl());
			OmsChargerBespeakBillRecord bespeakBillRecord = omsChargerBespeakBillRecordDao.findOneExample(bespeakBillRecord_query, null, null);

			if (bespeakBillRecord != null)
			{
				log.info("update reservation record");
				bespeakBillRecord.setActual_end_time(new Date());
				bespeakBillRecord.setStatus(OmsConstant.BespeakStatus.Charged);
				omsChargerBespeakBillRecordDao.updateObject(bespeakBillRecord);
			}
		}

		switch (charger.getCharger_type()) { // 1:直流  2:交流  3:混合
			case 1:
				OmsChargerStateDirect directState_query =  new OmsChargerStateDirect();
				directState_query.setPort_no(billRecord.getPort_no());
				directState_query.setCharger_id(chargerId);
				OmsChargerStateDirect directState =  omsChargerStateDirectDao.findOneExample(directState_query,null,null);
				directState.setCharge_status(2);
				directState.setCharge_jrnl(billRecord.getCharge_jrnl());
				directState.setBespeak_jrnl("");
				directState.setUser_pay_card(billRecord.getUser_pay_card());
				omsChargerStateDirectDao.updateObject(directState);
				if (charger.getIs_parallel_charge() == 0)
				{
					omsChargerStateDirectDao.exec("update oms_charger_state_direct set charge_status = 4 where charger_id = '" + chargerId + "' and port_no <> " + billRecord.getPort_no());
				}
				break;
			case 2:
				OmsChargerStateAlternate alternateState_query =  new OmsChargerStateAlternate();
				alternateState_query.setPort_no(billRecord.getPort_no());
				alternateState_query.setCharger_id(chargerId);
				OmsChargerStateAlternate alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query,null,null);
				alternateState.setCharge_status(2);
				alternateState.setCharge_jrnl(billRecord.getCharge_jrnl());
				alternateState.setBespeak_jrnl("");
				alternateState.setUser_pay_card(billRecord.getUser_pay_card());
				omsChargerStateAlternateDao.updateObject(alternateState);
				if (charger.getIs_parallel_charge() == 0)
				{
					omsChargerStateDirectDao.exec("update oms_charger_state_alternate set charge_status = 0 where charger_id = '" + chargerId + "' and port_no <> " + billRecord.getPort_no());
				}
				break;
			default:
				break;
		}

		// 通知appServer start
		AppChargeNotifyParam param = new AppChargeNotifyParam();
		param.setAction(AppServerConstant.CHARGE_NOTIFY_ACTION_CHARGE); // 开始充电
		if (billRecord.getBespeak_jrnl() == null || "".equals(billRecord.getBespeak_jrnl()))
			param.setChargeType("0"); // 非预约充电
		else
			param.setChargeType("1"); // 预约充电
		param.setStationName(charger.getStation_name());
		param.setSerialNo(charger.getSerial_no());
		param.setPlugNo(String.valueOf(billRecord.getPort_no()));
		param.setChargerId(chargerId);
		param.setUserCard(billRecord.getUser_pay_card());
		param.setChargeSn(billRecord.getCharge_jrnl());
		param.setStartTime(billRecord.getStart_time().toString());

		JsonCommon<String> result = systemAppServerRpcClient.chargeNotify(param);
		log.info(result);

		return StringUtil.getjsonCReturn("", "", "200", "ok");
	}
	//2.0的开始充电和结束充电都是以OMS时间为准
	@Override
	public JsonCommon<String> ec3v2stopChargeReturn(Map<String, String> map) throws Exception
	{
		String code, msg;
		log.info(map);
		if(!OmsConstant.MsgResponseCodeEnum.Normal.value().equals(map.get("msgResponseCode")))
			throw new BizException("Charger reply a non-normal response code");

		Date now = new Date();

		String msg_charge_end_jrnl = map.get("omsSerialNumber");
		log.info(msg_charge_end_jrnl);


		//更新充电费用记录表
		OmsChargerChargeBillRecord billRecord_query = new OmsChargerChargeBillRecord();
		billRecord_query.setMsg_charge_end_jrnl(msg_charge_end_jrnl);
		OmsChargerChargeBillRecord billRecord = omsChargerChargeBillRecordDao.findOneExample(billRecord_query, null, null);
		if (billRecord == null)
			throw new BizException("oms Charging Bill Record not found");
		log.info(billRecord.getCharge_jrnl());

		String chargerId = billRecord.getCharger_id();
		OmsCharger charger_query = new OmsCharger();
		charger_query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(charger_query, null, null);
		if (charger.getCharger_type() == null)
			throw new BizException("Charger not found");
		log.info(charger.getCharger_id());

//		billRecord.setEnd_time(now);

		String cardType = CardUtils.generateCardType(billRecord.getUser_pay_card());

		if (OmsConstant.CardTypeEnum.OnlineApp.equals(cardType) || OmsConstant.CardTypeEnum.OnlineCompany.equals(cardType))
			billRecord.setOffline_is_pay(2);
		else
			billRecord.setOffline_is_pay(0);

		billRecord.setStatus(OmsConstant.ChargingBillStatus.ChargingComplete);//4 充电结束 ：桩回复充电结束 ；

		omsChargerChargeBillRecordDao.updateObject(billRecord);

		//更新状态
		int chargerType = charger.getCharger_type();
		log.info(chargerType);
		switch (chargerType)
		{//1--直流  2--交流  3--混合
			case 1:
				OmsChargerStateDirect directState_query = new OmsChargerStateDirect();
				directState_query.setPort_no(billRecord.getPort_no());
				directState_query.setCharger_id(chargerId);
				OmsChargerStateDirect directState = omsChargerStateDirectDao.findOneExample(directState_query, null, null);
				directState.setCharge_status(0);//0: 空闲;1: 预约;2 充电; 3 故障
				directState.setOnline_status(1);
				directState.setCharge_jrnl("");
				directState.setUser_pay_card("");
				omsChargerStateDirectDao.updateObject(directState);
				if (charger.getIs_parallel_charge() == 0)
				{
					omsChargerStateDirectDao.exec("update oms_charger_state_direct set charge_status = 0 where charger_id = '" + chargerId + "' and port_no <> " + billRecord.getPort_no());
				}
				break;
			case 2:
				OmsChargerStateAlternate alternateState_query = new OmsChargerStateAlternate();
				alternateState_query.setPort_no(billRecord.getPort_no());
				alternateState_query.setCharger_id(chargerId);
				OmsChargerStateAlternate alternateState = omsChargerStateAlternateDao.findOneExample(alternateState_query, null, null);
				alternateState.setCharge_status(0);//0: 空闲;1: 预约;2 充电; 3 故障
				alternateState.setOnline_status(1);
				alternateState.setCharge_jrnl("");
				alternateState.setUser_pay_card("");
				omsChargerStateAlternateDao.updateObject(alternateState);
				if (charger.getIs_parallel_charge() == 0)
				{
					omsChargerStateDirectDao.exec("update oms_charger_state_alternate set charge_status = 0 where charger_id = '" + chargerId + "' and port_no <> " + billRecord.getPort_no());
				}
				break;
			default:
				break;
		}

		// 通知appServer start
		AppChargeNotifyParam param = new AppChargeNotifyParam();
		param.setAction(AppServerConstant.CHARGE_NOTIFY_ACTION_END_CHARGE); // 结束充电
		if (billRecord_query.getBespeak_jrnl() == null || "".equals(billRecord_query.getBespeak_jrnl()))
		{
			param.setChargeType("0"); // 非预约充电
		}
		else
		{
			param.setChargeType("1"); // 预约充电
		}
		param.setStationName(charger.getStation_name());
		param.setSerialNo(charger.getSerial_no());
		param.setPlugNo(String.valueOf(billRecord.getPort_no()));
		param.setChargerId(chargerId);
		param.setUserCard(billRecord.getUser_pay_card());
		param.setChargeSn(billRecord.getCharge_jrnl());
		param.setStartTime(billRecord.getStart_time().toString());

		JsonCommon<String> result = systemAppServerRpcClient.chargeNotify(param);
		log.info(result);
		// 通知appServer end

		code = "200";
		msg = "ok";
		return StringUtil.getjsonCReturn("", "", code, msg);
	}
	//未收到回复则桩仍然在线，收到回复就可以认为桩已经离线
	@Override
	public JsonCommon<String> ev3c2restartChargerReturn(Map<String, String> map) {
		String chargerId = map.get("chargerId");
		String chargerType = map.get("chargerType");// 0：交流桩   1：直流桩  F：其它
		String msgResponseCode = map.get("msgResponseCode");
		if(msgResponseCode.equals(OmsConstant.MsgResponseCodeEnum.NoFrameCode.value())){
			StringBuilder sb = new StringBuilder("update");
			switch (chargerType) {//1--直流  2--交流  3--混合
			case "1":
				sb.append(" oms_charger_state_direct set online_status =0  where chargerId ='"+chargerId+"'");
				omsChargerStateDirectDao.exec(sb.toString());
				break;
			case "2":
				sb.append(" oms_charger_state_alternate set online_status =0  where chargerId ='"+chargerId+"'");
				omsChargerStateAlternateDao.exec(sb.toString());
				break;
			default:
				break;
			}
		}
		return OmsConstant.jsonSuccess;
	}

	@Override
	public JsonCommon<String> queryOrSetParam(Map<String, String> map) {
		
		return null;
	}
	
}
